diff --git a/lisp/vc-git.el b/lisp/vc-git.el index 69e8614..6f60cb2 100644 --- a/lisp/vc-git.el +++ b/lisp/vc-git.el @@ -490,6 +490,51 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches." ;;; STATE-CHANGING FUNCTIONS +(defun vc-git--do-push-pull (operation) + "Calls the command git OPERATION. OPERATION could be 'push or 'pull." + (let* ((default-refspec (vc-git-working-revision buffer-file-name)) + (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)) + (default-repo (nth 0 available-repos)) + (current-repo + (completing-read (format "Repository (default %s): " default-repo) + available-repos nil 'confirm nil nil default-repo)) + (available-refspecs + (let ((table (list "HEAD")) + (ref-regexp)) + (with-temp-buffer + (vc-git-command t nil nil "for-each-ref" "--format=%(refname)") + (setq ref-regexp + (format (if (and (not (equal "." current-repo)) + (equal vc-git-push-pull-perform 'pull)) + "^refs/\\(remotes/%s\\|tags\\)/\\([^\n]+\\).*$" + "^refs/\\(remotes\\|heads\\|tags\\)/\\(%s/[^\n]+\\|[^\n]+\\).*$") + (regexp-quote current-repo))) + (goto-char (point-min)) + (while (re-search-forward ref-regexp nil t) + (push (match-string 2) table))) + table)) + (current-refspec + (completing-read (format "Branch (default %s): " default-refspec) + available-refspecs nil 'confirm nil nil + default-refspec)) + (command (prin1-to-string operation))) + (vc-git-command nil 0 nil command current-repo current-refspec))) + +(defun vc-git-push () + "Update remote refs along with associated objects." + (vc-git--do-push-pull 'push)) + +(defun vc-git-pull () + "Fetch from and merge with another repository or a local branch." + (vc-git--do-push-pull 'pull)) + (defun vc-git-create-repo () "Create a new Git repository." (vc-git-command nil 0 nil "init"))