diff --git a/lisp/vc-git.el b/lisp/vc-git.el index a33a0f5..bb95b70 100644 --- a/lisp/vc-git.el +++ b/lisp/vc-git.el @@ -489,6 +489,80 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." ;;; STATE-CHANGING FUNCTIONS +(defvar vc-git-push-pull-perform 'pull + "The git command `vc-git--do-push-pull' should execute") + +(defun vc-git--do-push-pull (repository refspec) + "Calls git push/pull with REPOSITORY and REFSPEC as parameters. + +The decision of using push or pull is beign made depending the +value of `vc-git-push-pull-perform'." + (interactive + (let ((default-refspec (vc-git-working-revision buffer-file-name)) + (default-repo) + (available-repos) + (available-refspecs) + (current-repo) + (current-refspec)) + (setq available-repos + (let ((table (list "."))) + (with-temp-buffer + (vc-git-command t nil nil "for-each-ref" "--format=%(refname)") + (goto-char (point-min)) + (while (re-search-forward "^refs/remotes/\\([^/]+\\).*$" nil t) + (push (match-string 1) table))) + table)) + (setq default-repo (nth 0 available-repos)) + (setq current-repo + (completing-read (format "Repository (default %s): " default-repo) + available-repos nil 'confirm nil nil default-repo)) + (setq available-refspecs + (let ((table (list "HEAD")) + (ref-regexp)) + (with-temp-buffer + (vc-git-command t nil nil "for-each-ref" "--format=%(refname)") + (if (and (not (equal "." current-repo)) + (equal vc-git-push-pull-perform 'pull)) + (setq ref-regexp (concat + "^refs/\\(remotes/" + (regexp-quote current-repo) + "\\|tags\\)/\\([^\n]+\\).*$")) + (setq ref-regexp (concat + "^refs/\\(remotes\\|heads\\|tags\\)/\\(" + (regexp-quote current-repo) + "/[^\n]+\\|[^\n]+\\).*$"))) + (goto-char (point-min)) + (while (re-search-forward + ref-regexp + nil t) + (push (match-string 2) table))) + table)) + (setq current-refspec + (completing-read (format "Branch (default %s): " default-refspec) + available-refspecs nil 'confirm nil nil + default-refspec)) + (list current-repo current-refspec))) + (let ((buffer (current-buffer)) + (command-buffer-name "*vc-push-pull*")) + (vc-git-command + command-buffer-name 0 nil + (prin1-to-string vc-git-push-pull-perform) repository refspec) + (set-buffer command-buffer-name) + (message (buffer-string)) + (set-buffer buffer))) + +(defun vc-git-push () + "Update remote refs along with associated objects." + (interactive) + (setq vc-git-push-pull-perform 'push) + (call-interactively 'vc-git--do-push-pull)) + +(defun vc-git-pull () + "Fetch from and merge with another repository or a local branch." + (interactive) + (setq vc-git-push-pull-perform 'pull) + (call-interactively 'vc-git--do-push-pull)) + (defun vc-git-create-repo () "Create a new Git repository." (vc-git-command nil 0 nil "init"))