aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--default.mk4
-rw-r--r--lisp/Makefile4
-rw-r--r--lisp/magit-clone.el88
-rw-r--r--lisp/magit-fetch.el157
-rw-r--r--lisp/magit-merge.el2
-rw-r--r--lisp/magit-pull.el151
-rw-r--r--lisp/magit-push.el342
-rw-r--r--lisp/magit-remote.el611
-rw-r--r--lisp/magit.el4
9 files changed, 755 insertions, 608 deletions
diff --git a/default.mk b/default.mk
index 62211f5..66a8d82 100644
--- a/default.mk
+++ b/default.mk
@@ -74,6 +74,10 @@ ELS += magit-obsolete.el
ELS += magit-sequence.el
ELS += magit-commit.el
ELS += magit-remote.el
+ELS += magit-clone.el
+ELS += magit-fetch.el
+ELS += magit-pull.el
+ELS += magit-push.el
ELS += magit-bisect.el
ELS += magit-stash.el
ELS += magit-blame.el
diff --git a/lisp/Makefile b/lisp/Makefile
index 94c949c..0a739db 100644
--- a/lisp/Makefile
+++ b/lisp/Makefile
@@ -41,6 +41,10 @@ magit-notes.elc: magit.elc
magit-sequence.elc: magit.elc
magit-commit.elc: magit.elc magit-sequence.elc
magit-remote.elc: magit.elc
+magit-clone.elc: magit.elc
+magit-fetch.elc: magit.elc
+magit-pull.elc: magit.elc
+magit-push.elc: magit.elc
magit-bisect.elc: magit.elc
magit-stash.elc: magit.elc
magit-blame.elc: magit.elc
diff --git a/lisp/magit-clone.el b/lisp/magit-clone.el
new file mode 100644
index 0000000..c257c0f
--- /dev/null
+++ b/lisp/magit-clone.el
@@ -0,0 +1,88 @@
+;;; magit-clone.el --- clone a repository -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018 The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors. If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit. If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements clone commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-clone-set-remote-head nil
+ "Whether cloning creates the symbolic-ref `<remote>/HEAD'."
+ :package-version '(magit . "2.4.2")
+ :group 'magit-commands
+ :type 'boolean)
+
+(defcustom magit-clone-set-remote.pushDefault 'ask
+ "Whether to set the value of `remote.pushDefault' after cloning.
+
+If t, then set without asking. If nil, then don't set. If
+`ask', then ask."
+ :package-version '(magit . "2.4.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "set" t)
+ (const :tag "ask" ask)
+ (const :tag "don't set" nil)))
+
+;;; Commands
+
+;;;###autoload
+(defun magit-clone (repository directory)
+ "Clone the REPOSITORY to DIRECTORY.
+Then show the status buffer for the new repository."
+ (interactive
+ (let ((url (magit-read-string-ns "Clone repository")))
+ (list url (read-directory-name
+ "Clone to: " nil nil nil
+ (and (string-match "\\([^/:]+?\\)\\(/?\\.git\\)?$" url)
+ (match-string 1 url))))))
+ (setq directory (file-name-as-directory (expand-file-name directory)))
+ (magit-run-git-async "clone" repository
+ (magit-convert-filename-for-git directory))
+ ;; Don't refresh the buffer we're calling from.
+ (process-put magit-this-process 'inhibit-refresh t)
+ (set-process-sentinel
+ magit-this-process
+ (lambda (process event)
+ (when (memq (process-status process) '(exit signal))
+ (let ((magit-process-raise-error t))
+ (magit-process-sentinel process event)))
+ (when (and (eq (process-status process) 'exit)
+ (= (process-exit-status process) 0))
+ (let ((default-directory directory))
+ (when (or (eq magit-clone-set-remote.pushDefault t)
+ (and magit-clone-set-remote.pushDefault
+ (y-or-n-p "Set `remote.pushDefault' to \"origin\"? ")))
+ (setf (magit-get "remote.pushDefault") "origin"))
+ (unless magit-clone-set-remote-head
+ (magit-remote-unset-head "origin")))
+ (with-current-buffer (process-get process 'command-buf)
+ (magit-status-internal directory))))))
+
+;;; _
+(provide 'magit-clone)
+;;; magit-clone.el ends here
diff --git a/lisp/magit-fetch.el b/lisp/magit-fetch.el
new file mode 100644
index 0000000..dc04233
--- /dev/null
+++ b/lisp/magit-fetch.el
@@ -0,0 +1,157 @@
+;;; magit-fetch.el --- download objects and refs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018 The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors. If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit. If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements fetch commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-fetch-modules-jobs 4
+ "Number of submodules to fetch in parallel.
+Ignored for Git versions before v2.8.0."
+ :package-version '(magit . "2.12.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "one at a time" nil) number))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-fetch-popup "magit-fetch" nil t)
+(magit-define-popup magit-fetch-popup
+ "Popup console for fetch commands."
+ :man-page "git-fetch"
+ :switches '((?p "Prune deleted branches" "--prune"))
+ :actions '("Configure"
+ (?C "variables..." magit-branch-config-popup)
+ "Fetch from"
+ (?p magit-get-push-remote magit-fetch-from-pushremote)
+ (?u magit-get-remote magit-fetch-from-upstream)
+ (?e "elsewhere" magit-fetch-other)
+ (?a "all remotes" magit-fetch-all)
+ "Fetch"
+ (?o "another branch" magit-fetch-branch)
+ (?r "explicit refspec" magit-fetch-refspec)
+ (?m "submodules" magit-fetch-modules))
+ :default-action 'magit-fetch
+ :max-action-columns 1)
+
+(defun magit-git-fetch (remote args)
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "fetch" remote args))
+
+;;;###autoload
+(defun magit-fetch-from-pushremote (args)
+ "Fetch from the push-remote of the current branch."
+ (interactive (list (magit-fetch-arguments)))
+ (--if-let (magit-get-push-remote)
+ (magit-git-fetch it args)
+ (--if-let (magit-get-current-branch)
+ (user-error "No push-remote is configured for %s" it)
+ (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-fetch-from-upstream (args)
+ "Fetch from the upstream repository of the current branch."
+ (interactive (list (magit-fetch-arguments)))
+ (--if-let (magit-get-remote)
+ (magit-git-fetch it args)
+ (--if-let (magit-get-current-branch)
+ (user-error "No upstream is configured for %s" it)
+ (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-fetch-other (remote args)
+ "Fetch from another repository."
+ (interactive (list (magit-read-remote "Fetch remote")
+ (magit-fetch-arguments)))
+ (magit-git-fetch remote args))
+
+;;;###autoload
+(defun magit-fetch-branch (remote branch args)
+ "Fetch a BRANCH from a REMOTE."
+ (interactive
+ (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
+ (list remote
+ (magit-read-remote-branch "Fetch branch" remote)
+ (magit-fetch-arguments))))
+ (magit-git-fetch remote (cons branch args)))
+
+;;;###autoload
+(defun magit-fetch-refspec (remote refspec args)
+ "Fetch a REFSPEC from a REMOTE."
+ (interactive
+ (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
+ (list remote
+ (magit-read-refspec "Fetch using refspec" remote)
+ (magit-fetch-arguments))))
+ (magit-git-fetch remote (cons refspec args)))
+
+;;;###autoload
+(defun magit-fetch-all (args)
+ "Fetch from all remotes."
+ (interactive (list (cl-intersection (magit-fetch-arguments)
+ (list "--verbose" "--prune")
+ :test #'equal)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "remote" "update" args))
+
+;;;###autoload
+(defun magit-fetch-all-prune ()
+ "Fetch from all remotes, and prune.
+Prune remote tracking branches for branches that have been
+removed on the respective remote."
+ (interactive)
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "remote" "update" "--prune"))
+
+;;;###autoload
+(defun magit-fetch-all-no-prune ()
+ "Fetch from all remotes."
+ (interactive)
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "remote" "update"))
+
+;;;###autoload
+(defun magit-fetch-modules (&optional all)
+ "Fetch all submodules.
+
+Option `magit-fetch-modules-jobs' controls how many submodules
+are being fetched in parallel. Also fetch the super-repository,
+because `git-fetch' does not support not doing that. With a
+prefix argument fetch all remotes."
+ (interactive "P")
+ (magit-with-toplevel
+ (magit-run-git-async
+ "fetch" "--verbose" "--recurse-submodules"
+ (and magit-fetch-modules-jobs
+ (version<= "2.8.0" (magit-git-version))
+ (list "-j" (number-to-string magit-fetch-modules-jobs)))
+ (and all "--all"))))
+
+;;; _
+(provide 'magit-fetch)
+;;; magit-fetch.el ends here
diff --git a/lisp/magit-merge.el b/lisp/magit-merge.el
index 8f68224..b5aa33e 100644
--- a/lisp/magit-merge.el
+++ b/lisp/magit-merge.el
@@ -29,6 +29,8 @@
(require 'magit)
+(declare-function magit-git-push "magit-push" (branch target args))
+
;;; Commands
;;;###autoload (autoload 'magit-merge-popup "magit" nil t)
diff --git a/lisp/magit-pull.el b/lisp/magit-pull.el
new file mode 100644
index 0000000..67abe43
--- /dev/null
+++ b/lisp/magit-pull.el
@@ -0,0 +1,151 @@
+;;; magit-pull.el --- update local objects and refs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018 The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors. If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit. If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements pull commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-pull-popup "magit-pull" nil t)
+(magit-define-popup magit-pull-popup
+ "Popup console for pull commands."
+ :man-page "git-pull"
+ :variables '("Configure"
+ (?r "branch.%s.rebase"
+ magit-cycle-branch*rebase
+ magit-pull-format-branch*rebase)
+ (?C "variables..." magit-branch-config-popup))
+ :actions '((lambda ()
+ (--if-let (magit-get-current-branch)
+ (concat
+ (propertize "Pull into " 'face 'magit-popup-heading)
+ (propertize it 'face 'magit-branch-local)
+ (propertize " from" 'face 'magit-popup-heading))
+ (propertize "Pull from" 'face 'magit-popup-heading)))
+ (?p magit-get-push-branch magit-pull-from-pushremote)
+ (?u magit-get-upstream-branch magit-pull-from-upstream)
+ (?e "elsewhere" magit-pull-branch))
+ :default-action 'magit-pull
+ :max-action-columns 1)
+
+;;;###autoload (autoload 'magit-pull-and-fetch-popup "magit-pull" nil t)
+(magit-define-popup magit-pull-and-fetch-popup
+ "Popup console for pull and fetch commands.
+
+This popup is intended as a replacement for the separate popups
+`magit-pull-popup' and `magit-fetch-popup'. To use it, add this
+to your init file:
+
+ (with-eval-after-load \\='magit-remote
+ (define-key magit-mode-map \"f\" \\='magit-pull-and-fetch-popup)
+ (define-key magit-mode-map \"F\" nil))
+
+The combined popup does not offer all commands and arguments
+available from the individual popups. Instead of the argument
+`--prune' and the command `magit-fetch-all' it uses two commands
+`magit-fetch-prune' and `magit-fetch-no-prune'. And the commands
+`magit-fetch-from-pushremote' and `magit-fetch-from-upstream' are
+missing. To add them use something like:
+
+ (with-eval-after-load \\='magit-remote
+ (magit-define-popup-action \\='magit-pull-and-fetch-popup ?U
+ \\='magit-get-upstream-branch
+ \\='magit-fetch-from-upstream-remote ?F)
+ (magit-define-popup-action \\='magit-pull-and-fetch-popup ?P
+ \\='magit-get-push-branch
+ \\='magit-fetch-from-push-remote ?F))"
+ :man-page "git-pull"
+ :variables '("Configure"
+ (?r "branch.%s.rebase"
+ magit-cycle-branch*rebase
+ magit-pull-format-branch*rebase)
+ (?C "variables..." magit-branch-config-popup))
+ :actions '((lambda ()
+ (--if-let (magit-get-current-branch)
+ (concat
+ (propertize "Pull into " 'face 'magit-popup-heading)
+ (propertize it 'face 'magit-branch-local)
+ (propertize " from" 'face 'magit-popup-heading))
+ (propertize "Pull from" 'face 'magit-popup-heading)))
+ (?p magit-get-push-branch magit-pull-from-pushremote)
+ (?u magit-get-upstream-branch magit-pull-from-upstream)
+ (?e "elsewhere" magit-pull-branch)
+ "Fetch from"
+ (?f "remotes" magit-fetch-all-no-prune)
+ (?F "remotes and prune" magit-fetch-all-prune)
+ "Fetch"
+ (?o "another branch" magit-fetch-branch)
+ (?s "explicit refspec" magit-fetch-refspec)
+ (?m "submodules" magit-fetch-modules))
+ :default-action 'magit-fetch
+ :max-action-columns 1)
+
+(defun magit-pull-format-branch*rebase ()
+ (magit--format-popup-variable:choices
+ (format "branch.%s.rebase" (or (magit-get-current-branch) "<name>"))
+ '("true" "false")
+ "false" "pull.rebase"))
+
+(defun magit-git-pull (source args)
+ (run-hooks 'magit-credential-hook)
+ (pcase-let ((`(,remote . ,branch)
+ (magit-split-branch-name source)))
+ (magit-run-git-with-editor "pull" args remote branch)))
+
+;;;###autoload
+(defun magit-pull-from-pushremote (args)
+ "Pull from the push-remote of the current branch."
+ (interactive (list (magit-pull-arguments)))
+ (--if-let (magit-get-push-branch)
+ (magit-git-pull it args)
+ (--if-let (magit-get-current-branch)
+ (user-error "No push-remote is configured for %s" it)
+ (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-pull-from-upstream (args)
+ "Pull from the upstream of the current branch."
+ (interactive (list (magit-pull-arguments)))
+ (--if-let (magit-get-upstream-branch)
+ (progn (run-hooks 'magit-credential-hook)
+ (magit-run-git-with-editor
+ "pull" args (car (magit-split-branch-name it))))
+ (--if-let (magit-get-current-branch)
+ (user-error "No upstream is configured for %s" it)
+ (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-pull-branch (source args)
+ "Pull from a branch read in the minibuffer."
+ (interactive (list (magit-read-remote-branch "Pull" nil nil nil t)
+ (magit-pull-arguments)))
+ (magit-git-pull source args))
+
+;;; _
+(provide 'magit-pull)
+;;; magit-pull.el ends here
diff --git a/lisp/magit-push.el b/lisp/magit-push.el
new file mode 100644
index 0000000..3018322
--- /dev/null
+++ b/lisp/magit-push.el
@@ -0,0 +1,342 @@
+;;; magit-push.el --- update remote objects and refs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018 The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors. If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit. If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements push commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-push-current-set-remote-if-missing t
+ "Whether to configure missing remotes before pushing.
+
+When nil, then the command `magit-push-current-to-pushremote' and
+`magit-push-current-to-upstream' do not appear in the push popup
+if the push-remote resp. upstream is not configured. If the user
+invokes one of these commands anyway, then it raises an error.
+
+When non-nil, then these commands always appear in the push
+popup. But if the required configuration is missing, then they
+do appear in a way that indicates that this is the case. If the
+user invokes one of them, then it asks for the necessary
+configuration, stores the configuration, and then uses it to push
+a first time.
+
+This option also affects whether the argument `--set-upstream' is
+available in the popup. If the value is t, then that argument is
+redundant. But note that changing the value of this option does
+not take affect immediately, the argument will only be added or
+removed after restarting Emacs."
+ :package-version '(magit . "2.6.0")
+ :group 'magit-commands
+ :type '(choice (const :tag "don't set" nil)
+ (const :tag "set branch.<name>.pushRemote" t)
+ (const :tag "set remote.pushDefault" default)))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-push-popup "magit-push" nil t)
+(magit-define-popup magit-push-popup
+ "Popup console for push commands."
+ :man-page "git-push"
+ :switches `((?f "Force with lease" "--force-with-lease")
+ (?F "Force" "--force")
+ (?h "Disable hooks" "--no-verify")
+ (?d "Dry run" "--dry-run")
+ ,@(and (not magit-push-current-set-remote-if-missing)
+ '((?u "Set upstream" "--set-upstream"))))
+ :actions '("Configure"
+ (?C "variables..." magit-branch-config-popup)
+ (lambda ()
+ (--when-let (magit-get-current-branch)
+ (concat (propertize "Push " 'face 'magit-popup-heading)
+ (propertize it 'face 'magit-branch-local)
+ (propertize " to" 'face 'magit-popup-heading))))
+ (?p magit--push-current-to-pushremote-desc
+ magit-push-current-to-pushremote)
+ (?u magit--push-current-to-upstream-desc
+ magit-push-current-to-upstream)
+ (?e "elsewhere\n" magit-push-current)
+ "Push"
+ (?o "another branch" magit-push-other)
+ (?T "a tag" magit-push-tag)
+ (?r "explicit refspecs" magit-push-refspecs)
+ (?t "all tags" magit-push-tags)
+ (?m "matching branches" magit-push-matching))
+ :max-action-columns 2)
+
+(defun magit-git-push (branch target args)
+ (run-hooks 'magit-credential-hook)
+ (pcase-let ((`(,remote . ,target)
+ (magit-split-branch-name target)))
+ (magit-run-git-async "push" "-v" args remote
+ (format "%s:refs/heads/%s" branch target))))
+
+;;;###autoload
+(defun magit-push-current-to-pushremote (args &optional push-remote)
+ "Push the current branch to `branch.<name>.pushRemote'.
+If that variable is unset, then push to `remote.pushDefault'.
+
+When `magit-push-current-set-remote-if-missing' is non-nil and
+the push-remote is not configured, then read the push-remote from
+the user, set it, and then push to it. With a prefix argument
+the push-remote can be changed before pushed to it."
+ (interactive
+ (list (magit-push-arguments)
+ (and (magit--push-current-set-pushremote-p current-prefix-arg)
+ (magit-read-remote
+ (if (eq magit-push-current-set-remote-if-missing 'default)
+ "Set `remote.pushDefault' and push there"
+ (format "Set `branch.%s.pushRemote' and push there"
+ (magit-get-current-branch)))))))
+ (--if-let (magit-get-current-branch)
+ (progn (when push-remote
+ (setf (magit-get
+ (if (eq magit-push-current-set-remote-if-missing 'default)
+ "remote.pushDefault"
+ (format "branch.%s.pushRemote" it)))
+ push-remote))
+ (if-let ((remote (magit-get-push-remote it)))
+ (if (member remote (magit-list-remotes))
+ (magit-git-push it (concat remote "/" it) args)
+ (user-error "Remote `%s' doesn't exist" remote))
+ (user-error "No push-remote is configured for %s" it)))
+ (user-error "No branch is checked out")))
+
+(defun magit--push-current-set-pushremote-p (&optional change)
+ (and (or change
+ (and magit-push-current-set-remote-if-missing
+ (not (magit-get-push-remote))))
+ (magit-get-current-branch)))
+
+(defun magit--push-current-to-pushremote-desc ()
+ (--if-let (magit-get-push-branch)
+ (concat (magit-branch-set-face it) "\n")
+ (and (magit--push-current-set-pushremote-p)
+ (concat
+ (propertize (if (eq magit-push-current-set-remote-if-missing 'default)
+ "pushDefault"
+ "pushRemote")
+ 'face 'bold)
+ ", after setting that\n"))))
+
+;;;###autoload
+(defun magit-push-current-to-upstream (args &optional upstream)
+ "Push the current branch to its upstream branch.
+
+When `magit-push-current-set-remote-if-missing' is non-nil and
+the upstream is not configured, then read the upstream from the
+user, set it, and then push to it. With a prefix argument the
+upstream can be changed before pushed to it."
+ (interactive
+ (list (magit-push-arguments)
+ (and (magit--push-current-set-upstream-p current-prefix-arg)
+ (magit-read-upstream-branch))))
+ (--if-let (magit-get-current-branch)
+ (progn
+ (when upstream
+ (magit-set-upstream-branch it upstream))
+ (if-let ((target (magit-get-upstream-branch it)))
+ (magit-git-push it target args)
+ (user-error "No upstream is configured for %s" it)))
+ (user-error "No branch is checked out")))
+
+(defun magit--push-current-set-upstream-p (&optional change)
+ (and (or change
+ (and magit-push-current-set-remote-if-missing
+ (not (magit-get-upstream-branch))))
+ (magit-get-current-branch)))
+
+(defun magit--push-current-to-upstream-desc ()
+ (--if-let (magit-get-upstream-branch)
+ (concat (magit-branch-set-face it) "\n")
+ (and (magit--push-current-set-upstream-p)
+ (concat (propertize "@{upstream}" 'face 'bold)
+ ", after setting that\n"))))
+
+;;;###autoload
+(defun magit-push-current (target args)
+ "Push the current branch to a branch read in the minibuffer."
+ (interactive
+ (--if-let (magit-get-current-branch)
+ (list (magit-read-remote-branch (format "Push %s to" it)
+ nil nil it 'confirm)
+ (magit-push-arguments))
+ (user-error "No branch is checked out")))
+ (magit-git-push (magit-get-current-branch) target args))
+
+;;;###autoload
+(defun magit-push-other (source target args)
+ "Push an arbitrary branch or commit somewhere.
+Both the source and the target are read in the minibuffer."
+ (interactive
+ (let ((source (magit-read-local-branch-or-commit "Push")))
+ (list source
+ (magit-read-remote-branch
+ (format "Push %s to" source) nil
+ (if (magit-local-branch-p source)
+ (or (magit-get-push-branch source)
+ (magit-get-upstream-branch source))
+ (and (magit-rev-ancestor-p source "HEAD")
+ (or (magit-get-push-branch)
+ (magit-get-upstream-branch))))
+ source 'confirm)
+ (magit-push-arguments))))
+ (magit-git-push source target args))
+
+(defvar magit-push-refspecs-history nil)
+
+;;;###autoload
+(defun magit-push-refspecs (remote refspecs args)
+ "Push one or multiple REFSPECS to a REMOTE.
+Both the REMOTE and the REFSPECS are read in the minibuffer. To
+use multiple REFSPECS, separate them with commas. Completion is
+only available for the part before the colon, or when no colon
+is used."
+ (interactive
+ (list (magit-read-remote "Push to remote")
+ (split-string (magit-completing-read-multiple
+ "Push refspec,s"
+ (cons "HEAD" (magit-list-local-branch-names))
+ nil nil 'magit-push-refspecs-history)
+ crm-default-separator t)
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote refspecs))
+
+;;;###autoload
+(defun magit-push-matching (remote &optional args)
+ "Push all matching branches to another repository.
+If multiple remotes exist, then read one from the user.
+If just one exists, use that without requiring confirmation."
+ (interactive (list (magit-read-remote "Push matching branches to" nil t)
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote ":"))
+
+;;;###autoload
+(defun magit-push-tags (remote &optional args)
+ "Push all tags to another repository.
+If only one remote exists, then push to that. Otherwise prompt
+for a remote, offering the remote configured for the current
+branch as default."
+ (interactive (list (magit-read-remote "Push tags to remote" nil t)
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" remote "--tags" args))
+
+;;;###autoload
+(defun magit-push-tag (tag remote &optional args)
+ "Push a tag to another repository."
+ (interactive
+ (let ((tag (magit-read-tag "Push tag")))
+ (list tag (magit-read-remote (format "Push %s to remote" tag) nil t)
+ (magit-push-arguments))))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" remote tag args))
+
+;;;###autoload
+(defun magit-push-implicitly (args)
+ "Push somewhere without using an explicit refspec.
+
+This command simply runs \"git push -v [ARGS]\". ARGS are the
+arguments specified in the popup buffer. No explicit refspec
+arguments are used. Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+To add this command to the push popup add this to your init file:
+
+ (with-eval-after-load \\='magit-remote
+ (magit-define-popup-action \\='magit-push-popup ?P
+ \\='magit-push-implicitly--desc
+ \\='magit-push-implicitly ?p t))
+
+The function `magit-push-implicitly--desc' attempts to predict
+what this command will do. The value it returns is displayed in
+the popup buffer."
+ (interactive (list (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args))
+
+(defun magit-push-implicitly--desc ()
+ (let ((default (magit-get "push.default")))
+ (unless (equal default "nothing")
+ (or (when-let ((remote (or (magit-get-remote)
+ (magit-remote-p "origin")))
+ (refspec (magit-get "remote" remote "push")))
+ (format "%s using %s"
+ (propertize remote 'face 'magit-branch-remote)
+ (propertize refspec 'face 'bold)))
+ (--when-let (and (not (magit-get-push-branch))
+ (magit-get-upstream-branch))
+ (format "%s aka %s\n"
+ (magit-branch-set-face it)
+ (propertize "@{upstream}" 'face 'bold)))
+ (--when-let (magit-get-push-branch)
+ (format "%s aka %s\n"
+ (magit-branch-set-face it)
+ (propertize "pushRemote" 'face 'bold)))
+ (--when-let (magit-get-@{push}-branch)
+ (format "%s aka %s\n"
+ (magit-branch-set-face it)
+ (propertize "@{push}" 'face 'bold)))
+ (format "using %s (%s is %s)\n"
+ (propertize "git push" 'face 'bold)
+ (propertize "push.default" 'face 'bold)
+ (propertize default 'face 'bold))))))
+
+;;;###autoload
+(defun magit-push-to-remote (remote args)
+ "Push to REMOTE without using an explicit refspec.
+The REMOTE is read in the minibuffer.
+
+This command simply runs \"git push -v [ARGS] REMOTE\". ARGS
+are the arguments specified in the popup buffer. No refspec
+arguments are used. Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+To add this command to the push popup add this to your init file:
+
+ (with-eval-after-load \\='magit-remote
+ (magit-define-popup-action \\='magit-push-popup ?r
+ \\='magit-push-to-remote--desc
+ \\='magit-push-to-remote ?p t))"
+ (interactive (list (magit-read-remote "Push to remote")
+ (magit-push-arguments)))
+ (run-hooks 'magit-credential-hook)
+ (magit-run-git-async "push" "-v" args remote))
+
+(defun magit-push-to-remote--desc ()
+ (format "using %s\n" (propertize "git push <remote>" 'face 'bold)))
+
+;;; _
+(provide 'magit-push)
+;;; magit-push.el ends here
diff --git a/lisp/magit-remote.el b/lisp/magit-remote.el
index 8ba6d1e..afb7e59 100644
--- a/lisp/magit-remote.el
+++ b/lisp/magit-remote.el
@@ -23,9 +23,7 @@
;;; Commentary:
-;; This library implements support for interacting with remote
-;; repositories. Commands for cloning, fetching, pulling, and
-;; pushing are defined here.
+;; This library implements remote commands.
;;; Code:
@@ -33,68 +31,6 @@
;;; Options
-(defcustom magit-fetch-modules-jobs 4
- "Number of submodules to fetch in parallel.
-Ignored for Git versions before v2.8.0."
- :package-version '(magit . "2.12.0")
- :group 'magit-commands
- :type '(choice (const :tag "one at a time" nil) number))
-
-;;; Clone
-
-(defcustom magit-clone-set-remote-head nil
- "Whether cloning creates the symbolic-ref `<remote>/HEAD'."
- :package-version '(magit . "2.4.2")
- :group 'magit-commands
- :type 'boolean)
-
-(defcustom magit-clone-set-remote.pushDefault 'ask
- "Whether to set the value of `remote.pushDefault' after cloning.
-
-If t, then set without asking. If nil, then don't set. If
-`ask', then ask."
- :package-version '(magit . "2.4.0")
- :group 'magit-commands
- :type '(choice (const :tag "set" t)
- (const :tag "ask" ask)
- (const :tag "don't set" nil)))
-
-;;;###autoload
-(defun magit-clone (repository directory)
- "Clone the REPOSITORY to DIRECTORY.
-Then show the status buffer for the new repository."
- (interactive
- (let ((url (magit-read-string-ns "Clone repository")))
- (list url (read-directory-name
- "Clone to: " nil nil nil
- (and (string-match "\\([^/:]+?\\)\\(/?\\.git\\)?$" url)
- (match-string 1 url))))))
- (setq directory (file-name-as-directory (expand-file-name directory)))
- (magit-run-git-async "clone" repository
- (magit-convert-filename-for-git directory))
- ;; Don't refresh the buffer we're calling from.
- (process-put magit-this-process 'inhibit-refresh t)
- (set-process-sentinel
- magit-this-process
- (lambda (process event)
- (when (memq (process-status process) '(exit signal))
- (let ((magit-process-raise-error t))
- (magit-process-sentinel process event)))
- (when (and (eq (process-status process) 'exit)
- (= (process-exit-status process) 0))
- (let ((default-directory directory))
- (when (or (eq magit-clone-set-remote.pushDefault t)
- (and magit-clone-set-remote.pushDefault
- (y-or-n-p "Set `remote.pushDefault' to \"origin\"? ")))
- (setf (magit-get "remote.pushDefault") "origin"))
- (unless magit-clone-set-remote-head
- (magit-remote-unset-head "origin")))
- (with-current-buffer (process-get process 'command-buf)
- (magit-status-internal directory))))))
-
-;;; Remote
-;;;; Options
-
(defcustom magit-remote-add-set-remote.pushDefault 'ask-if-unset
"Whether to set the value of `remote.pushDefault' after adding a remote.
@@ -119,7 +55,7 @@ to be used to view and change remote related variables."
:group 'magit-commands
:type 'boolean)
-;;;; Popup
+;;; Commands
(defvar magit-remote-config-variables)
@@ -141,8 +77,6 @@ to be used to view and change remote related variables."
(?P "Prune stale refspecs" magit-remote-prune-refspecs))
:max-action-columns 2)
-;;;; Commands
-
(defun magit-read-url (prompt &optional initial-input)
(let ((url (magit-read-string-ns prompt initial-input)))
(if (string-prefix-p "~" url)
@@ -302,7 +236,7 @@ Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\"."
(interactive (list (magit-read-remote "Unset HEAD for remote")))
(magit-run-git "remote" "set-head" remote "--delete"))
-;;;; Config Popup
+;;; Configure
(defvar magit-remote-config--remote nil)
@@ -365,8 +299,6 @@ Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\"."
(and (magit-remote-p "origin") "origin")
remote)))
-;;;; Config Commands and Inserters
-
(defun magit-set-remote*url (remote urls)
"Set the variable `url' for the remote named REMOTE to URLS."
(interactive (magit-remote-config--read-args "url" "Urls: "))
@@ -439,543 +371,6 @@ Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\"."
(format "remote.%s.%s" (magit-remote-config--remote) variable)
25))
-;;; Fetch
-
-;;;###autoload (autoload 'magit-fetch-popup "magit-remote" nil t)
-(magit-define-popup magit-fetch-popup
- "Popup console for fetch commands."
- :man-page "git-fetch"
- :switches '((?p "Prune deleted branches" "--prune"))
- :actions '("Configure"
- (?C "variables..." magit-branch-config-popup)
- "Fetch from"
- (?p magit-get-push-remote magit-fetch-from-pushremote)
- (?u magit-get-remote magit-fetch-from-upstream)
- (?e "elsewhere" magit-fetch-other)
- (?a "all remotes" magit-fetch-all)
- "Fetch"
- (?o "another branch" magit-fetch-branch)
- (?r "explicit refspec" magit-fetch-refspec)
- (?m "submodules" magit-fetch-modules))
- :default-action 'magit-fetch
- :max-action-columns 1)
-
-(defun magit-git-fetch (remote args)
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "fetch" remote args))
-
-;;;###autoload
-(defun magit-fetch-from-pushremote (args)
- "Fetch from the push-remote of the current branch."
- (interactive (list (magit-fetch-arguments)))
- (--if-let (magit-get-push-remote)
- (magit-git-fetch it args)
- (--if-let (magit-get-current-branch)
- (user-error "No push-remote is configured for %s" it)
- (user-error "No branch is checked out"))))
-
-;;;###autoload
-(defun magit-fetch-from-upstream (args)
- "Fetch from the upstream repository of the current branch."
- (interactive (list (magit-fetch-arguments)))
- (--if-let (magit-get-remote)
- (magit-git-fetch it args)
- (--if-let (magit-get-current-branch)
- (user-error "No upstream is configured for %s" it)
- (user-error "No branch is checked out"))))
-
-;;;###autoload
-(defun magit-fetch-other (remote args)
- "Fetch from another repository."
- (interactive (list (magit-read-remote "Fetch remote")
- (magit-fetch-arguments)))
- (magit-git-fetch remote args))
-
-;;;###autoload
-(defun magit-fetch-branch (remote branch args)
- "Fetch a BRANCH from a REMOTE."
- (interactive
- (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
- (list remote
- (magit-read-remote-branch "Fetch branch" remote)
- (magit-fetch-arguments))))
- (magit-git-fetch remote (cons branch args)))
-
-;;;###autoload
-(defun magit-fetch-refspec (remote refspec args)
- "Fetch a REFSPEC from a REMOTE."
- (interactive
- (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
- (list remote
- (magit-read-refspec "Fetch using refspec" remote)
- (magit-fetch-arguments))))
- (magit-git-fetch remote (cons refspec args)))
-
-;;;###autoload
-(defun magit-fetch-all (args)
- "Fetch from all remotes."
- (interactive (list (cl-intersection (magit-fetch-arguments)
- (list "--verbose" "--prune")
- :test #'equal)))
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "remote" "update" args))
-
-;;;###autoload
-(defun magit-fetch-all-prune ()
- "Fetch from all remotes, and prune.
-Prune remote tracking branches for branches that have been
-removed on the respective remote."
- (interactive)
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "remote" "update" "--prune"))
-
-;;;###autoload
-(defun magit-fetch-all-no-prune ()
- "Fetch from all remotes."
- (interactive)
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "remote" "update"))
-
-;;;###autoload
-(defun magit-fetch-modules (&optional all)
- "Fetch all submodules.
-
-Option `magit-fetch-modules-jobs' controls how many submodules
-are being fetched in parallel. Also fetch the super-repository,
-because `git-fetch' does not support not doing that. With a
-prefix argument fetch all remotes."
- (interactive "P")
- (magit-with-toplevel
- (magit-run-git-async
- "fetch" "--verbose" "--recurse-submodules"
- (and magit-fetch-modules-jobs
- (version<= "2.8.0" (magit-git-version))
- (list "-j" (number-to-string magit-fetch-modules-jobs)))
- (and all "--all"))))
-
-;;; Pull
-
-;;;###autoload (autoload 'magit-pull-popup "magit-remote" nil t)
-(magit-define-popup magit-pull-popup
- "Popup console for pull commands."
- :man-page "git-pull"
- :variables '("Configure"
- (?r "branch.%s.rebase"
- magit-cycle-branch*rebase
- magit-pull-format-branch*rebase)
- (?C "variables..." magit-branch-config-popup))
- :actions '((lambda ()
- (--if-let (magit-get-current-branch)
- (concat
- (propertize "Pull into " 'face 'magit-popup-heading)
- (propertize it 'face 'magit-branch-local)
- (propertize " from" 'face 'magit-popup-heading))
- (propertize "Pull from" 'face 'magit-popup-heading)))
- (?p magit-get-push-branch magit-pull-from-pushremote)
- (?u magit-get-upstream-branch magit-pull-from-upstream)
- (?e "elsewhere" magit-pull-branch))
- :default-action 'magit-pull
- :max-action-columns 1)
-
-;;;###autoload (autoload 'magit-pull-and-fetch-popup "magit-remote" nil t)
-(magit-define-popup magit-pull-and-fetch-popup
- "Popup console for pull and fetch commands.
-
-This popup is intended as a replacement for the separate popups
-`magit-pull-popup' and `magit-fetch-popup'. To use it, add this
-to your init file:
-
- (with-eval-after-load \\='magit-remote
- (define-key magit-mode-map \"f\" \\='magit-pull-and-fetch-popup)
- (define-key magit-mode-map \"F\" nil))
-
-The combined popup does not offer all commands and arguments
-available from the individual popups. Instead of the argument
-`--prune' and the command `magit-fetch-all' it uses two commands
-`magit-fetch-prune' and `magit-fetch-no-prune'. And the commands
-`magit-fetch-from-pushremote' and `magit-fetch-from-upstream' are
-missing. To add them use something like:
-
- (with-eval-after-load \\='magit-remote
- (magit-define-popup-action \\='magit-pull-and-fetch-popup ?U
- \\='magit-get-upstream-branch
- \\='magit-fetch-from-upstream-remote ?F)
- (magit-define-popup-action \\='magit-pull-and-fetch-popup ?P
- \\='magit-get-push-branch
- \\='magit-fetch-from-push-remote ?F))"
- :man-page "git-pull"
- :variables '("Configure"
- (?r "branch.%s.rebase"
- magit-cycle-branch*rebase
- magit-pull-format-branch*rebase)
- (?C "variables..." magit-branch-config-popup))
- :actions '((lambda ()
- (--if-let (magit-get-current-branch)
- (concat
- (propertize "Pull into " 'face 'magit-popup-heading)
- (propertize it 'face 'magit-branch-local)
- (propertize " from" 'face 'magit-popup-heading))
- (propertize "Pull from" 'face 'magit-popup-heading)))
- (?p magit-get-push-branch magit-pull-from-pushremote)
- (?u magit-get-upstream-branch magit-pull-from-upstream)
- (?e "elsewhere" magit-pull-branch)
- "Fetch from"
- (?f "remotes" magit-fetch-all-no-prune)
- (?F "remotes and prune" magit-fetch-all-prune)
- "Fetch"
- (?o "another branch" magit-fetch-branch)
- (?s "explicit refspec" magit-fetch-refspec)
- (?m "submodules" magit-fetch-modules))
- :default-action 'magit-fetch
- :max-action-columns 1)
-
-(defun magit-pull-format-branch*rebase ()
- (magit--format-popup-variable:choices
- (format "branch.%s.rebase" (or (magit-get-current-branch) "<name>"))
- '("true" "false")
- "false" "pull.rebase"))
-
-(defun magit-git-pull (source args)
- (run-hooks 'magit-credential-hook)
- (pcase-let ((`(,remote . ,branch)
- (magit-split-branch-name source)))
- (magit-run-git-with-editor "pull" args remote branch)))
-
-;;;###autoload
-(defun magit-pull-from-pushremote (args)
- "Pull from the push-remote of the current branch."
- (interactive (list (magit-pull-arguments)))
- (--if-let (magit-get-push-branch)
- (magit-git-pull it args)
- (--if-let (magit-get-current-branch)
- (user-error "No push-remote is configured for %s" it)
- (user-error "No branch is checked out"))))
-
-;;;###autoload
-(defun magit-pull-from-upstream (args)
- "Pull from the upstream of the current branch."
- (interactive (list (magit-pull-arguments)))
- (--if-let (magit-get-upstream-branch)
- (progn (run-hooks 'magit-credential-hook)
- (magit-run-git-with-editor
- "pull" args (car (magit-split-branch-name it))))
- (--if-let (magit-get-current-branch)
- (user-error "No upstream is configured for %s" it)
- (user-error "No branch is checked out"))))
-
-;;;###autoload
-(defun magit-pull-branch (source args)
- "Pull from a branch read in the minibuffer."
- (interactive (list (magit-read-remote-branch "Pull" nil nil nil t)
- (magit-pull-arguments)))
- (magit-git-pull source args))
-
-;;; Push
-
-(defcustom magit-push-current-set-remote-if-missing t
- "Whether to configure missing remotes before pushing.
-
-When nil, then the command `magit-push-current-to-pushremote' and
-`magit-push-current-to-upstream' do not appear in the push popup
-if the push-remote resp. upstream is not configured. If the user
-invokes one of these commands anyway, then it raises an error.
-
-When non-nil, then these commands always appear in the push
-popup. But if the required configuration is missing, then they
-do appear in a way that indicates that this is the case. If the
-user invokes one of them, then it asks for the necessary
-configuration, stores the configuration, and then uses it to push
-a first time.
-
-This option also affects whether the argument `--set-upstream' is
-available in the popup. If the value is t, then that argument is
-redundant. But note that changing the value of this option does
-not take affect immediately, the argument will only be added or
-removed after restarting Emacs."
- :package-version '(magit . "2.6.0")
- :group 'magit-commands
- :type '(choice (const :tag "don't set" nil)
- (const :tag "set branch.<name>.pushRemote" t)
- (const :tag "set remote.pushDefault" default)))
-
-;;;###autoload (autoload 'magit-push-popup "magit-remote" nil t)
-(magit-define-popup magit-push-popup
- "Popup console for push commands."
- :man-page "git-push"
- :switches `((?f "Force with lease" "--force-with-lease")
- (?F "Force" "--force")
- (?h "Disable hooks" "--no-verify")
- (?d "Dry run" "--dry-run")
- ,@(and (not magit-push-current-set-remote-if-missing)
- '((?u "Set upstream" "--set-upstream"))))
- :actions '("Configure"
- (?C "variables..." magit-branch-config-popup)
- (lambda ()
- (--when-let (magit-get-current-branch)
- (concat (propertize "Push " 'face 'magit-popup-heading)
- (propertize it 'face 'magit-branch-local)
- (propertize " to" 'face 'magit-popup-heading))))
- (?p magit--push-current-to-pushremote-desc
- magit-push-current-to-pushremote)
- (?u magit--push-current-to-upstream-desc
- magit-push-current-to-upstream)
- (?e "elsewhere\n" magit-push-current)
- "Push"
- (?o "another branch" magit-push-other)
- (?T "a tag" magit-push-tag)
- (?r "explicit refspecs" magit-push-refspecs)
- (?t "all tags" magit-push-tags)
- (?m "matching branches" magit-push-matching))
- :max-action-columns 2)
-
-(defun magit-git-push (branch target args)
- (run-hooks 'magit-credential-hook)
- (pcase-let ((`(,remote . ,target)
- (magit-split-branch-name target)))
- (magit-run-git-async "push" "-v" args remote
- (format "%s:refs/heads/%s" branch target))))
-
-;;;###autoload
-(defun magit-push-current-to-pushremote (args &optional push-remote)
- "Push the current branch to `branch.<name>.pushRemote'.
-If that variable is unset, then push to `remote.pushDefault'.
-
-When `magit-push-current-set-remote-if-missing' is non-nil and
-the push-remote is not configured, then read the push-remote from
-the user, set it, and then push to it. With a prefix argument
-the push-remote can be changed before pushed to it."
- (interactive
- (list (magit-push-arguments)
- (and (magit--push-current-set-pushremote-p current-prefix-arg)
- (magit-read-remote
- (if (eq magit-push-current-set-remote-if-missing 'default)
- "Set `remote.pushDefault' and push there"
- (format "Set `branch.%s.pushRemote' and push there"
- (magit-get-current-branch)))))))
- (--if-let (magit-get-current-branch)
- (progn (when push-remote
- (setf (magit-get
- (if (eq magit-push-current-set-remote-if-missing 'default)
- "remote.pushDefault"
- (format "branch.%s.pushRemote" it)))
- push-remote))
- (if-let ((remote (magit-get-push-remote it)))
- (if (member remote (magit-list-remotes))
- (magit-git-push it (concat remote "/" it) args)
- (user-error "Remote `%s' doesn't exist" remote))
- (user-error "No push-remote is configured for %s" it)))
- (user-error "No branch is checked out")))
-
-(defun magit--push-current-set-pushremote-p (&optional change)
- (and (or change
- (and magit-push-current-set-remote-if-missing
- (not (magit-get-push-remote))))
- (magit-get-current-branch)))
-
-(defun magit--push-current-to-pushremote-desc ()
- (--if-let (magit-get-push-branch)
- (concat (magit-branch-set-face it) "\n")
- (and (magit--push-current-set-pushremote-p)
- (concat
- (propertize (if (eq magit-push-current-set-remote-if-missing 'default)
- "pushDefault"
- "pushRemote")
- 'face 'bold)
- ", after setting that\n"))))
-
-;;;###autoload
-(defun magit-push-current-to-upstream (args &optional upstream)
- "Push the current branch to its upstream branch.
-
-When `magit-push-current-set-remote-if-missing' is non-nil and
-the upstream is not configured, then read the upstream from the
-user, set it, and then push to it. With a prefix argument the
-upstream can be changed before pushed to it."
- (interactive
- (list (magit-push-arguments)
- (and (magit--push-current-set-upstream-p current-prefix-arg)
- (magit-read-upstream-branch))))
- (--if-let (magit-get-current-branch)
- (progn
- (when upstream
- (magit-set-upstream-branch it upstream))
- (if-let ((target (magit-get-upstream-branch it)))
- (magit-git-push it target args)
- (user-error "No upstream is configured for %s" it)))
- (user-error "No branch is checked out")))
-
-(defun magit--push-current-set-upstream-p (&optional change)
- (and (or change
- (and magit-push-current-set-remote-if-missing
- (not (magit-get-upstream-branch))))
- (magit-get-current-branch)))
-
-(defun magit--push-current-to-upstream-desc ()
- (--if-let (magit-get-upstream-branch)
- (concat (magit-branch-set-face it) "\n")
- (and (magit--push-current-set-upstream-p)
- (concat (propertize "@{upstream}" 'face 'bold)
- ", after setting that\n"))))
-
-;;;###autoload
-(defun magit-push-current (target args)
- "Push the current branch to a branch read in the minibuffer."
- (interactive
- (--if-let (magit-get-current-branch)
- (list (magit-read-remote-branch (format "Push %s to" it)
- nil nil it 'confirm)
- (magit-push-arguments))
- (user-error "No branch is checked out")))
- (magit-git-push (magit-get-current-branch) target args))
-
-;;;###autoload
-(defun magit-push-other (source target args)
- "Push an arbitrary branch or commit somewhere.
-Both the source and the target are read in the minibuffer."
- (interactive
- (let ((source (magit-read-local-branch-or-commit "Push")))
- (list source
- (magit-read-remote-branch
- (format "Push %s to" source) nil
- (if (magit-local-branch-p source)
- (or (magit-get-push-branch source)
- (magit-get-upstream-branch source))
- (and (magit-rev-ancestor-p source "HEAD")
- (or (magit-get-push-branch)
- (magit-get-upstream-branch))))
- source 'confirm)
- (magit-push-arguments))))
- (magit-git-push source target args))
-
-(defvar magit-push-refspecs-history nil)
-
-;;;###autoload
-(defun magit-push-refspecs (remote refspecs args)
- "Push one or multiple REFSPECS to a REMOTE.
-Both the REMOTE and the REFSPECS are read in the minibuffer. To
-use multiple REFSPECS, separate them with commas. Completion is
-only available for the part before the colon, or when no colon
-is used."
- (interactive
- (list (magit-read-remote "Push to remote")
- (split-string (magit-completing-read-multiple
- "Push refspec,s"
- (cons "HEAD" (magit-list-local-branch-names))
- nil nil 'magit-push-refspecs-history)
- crm-default-separator t)
- (magit-push-arguments)))
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "push" "-v" args remote refspecs))
-
-;;;###autoload
-(defun magit-push-matching (remote &optional args)
- "Push all matching branches to another repository.
-If multiple remotes exist, then read one from the user.
-If just one exists, use that without requiring confirmation."
- (interactive (list (magit-read-remote "Push matching branches to" nil t)
- (magit-push-arguments)))
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "push" "-v" args remote ":"))
-
-;;;###autoload
-(defun magit-push-tags (remote &optional args)
- "Push all tags to another repository.
-If only one remote exists, then push to that. Otherwise prompt
-for a remote, offering the remote configured for the current
-branch as default."
- (interactive (list (magit-read-remote "Push tags to remote" nil t)
- (magit-push-arguments)))
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "push" remote "--tags" args))
-
-;;;###autoload
-(defun magit-push-tag (tag remote &optional args)
- "Push a tag to another repository."
- (interactive
- (let ((tag (magit-read-tag "Push tag")))
- (list tag (magit-read-remote (format "Push %s to remote" tag) nil t)
- (magit-push-arguments))))
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "push" remote tag args))
-
-;;;###autoload
-(defun magit-push-implicitly (args)
- "Push somewhere without using an explicit refspec.
-
-This command simply runs \"git push -v [ARGS]\". ARGS are the
-arguments specified in the popup buffer. No explicit refspec
-arguments are used. Instead the behavior depends on at least
-these Git variables: `push.default', `remote.pushDefault',
-`branch.<branch>.pushRemote', `branch.<branch>.remote',
-`branch.<branch>.merge', and `remote.<remote>.push'.
-
-To add this command to the push popup add this to your init file:
-
- (with-eval-after-load \\='magit-remote
- (magit-define-popup-action \\='magit-push-popup ?P
- \\='magit-push-implicitly--desc
- \\='magit-push-implicitly ?p t))
-
-The function `magit-push-implicitly--desc' attempts to predict
-what this command will do. The value it returns is displayed in
-the popup buffer."
- (interactive (list (magit-push-arguments)))
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "push" "-v" args))
-
-(defun magit-push-implicitly--desc ()
- (let ((default (magit-get "push.default")))
- (unless (equal default "nothing")
- (or (when-let ((remote (or (magit-get-remote)
- (magit-remote-p "origin")))
- (refspec (magit-get "remote" remote "push")))
- (format "%s using %s"
- (propertize remote 'face 'magit-branch-remote)
- (propertize refspec 'face 'bold)))
- (--when-let (and (not (magit-get-push-branch))
- (magit-get-upstream-branch))
- (format "%s aka %s\n"
- (magit-branch-set-face it)
- (propertize "@{upstream}" 'face 'bold)))
- (--when-let (magit-get-push-branch)
- (format "%s aka %s\n"
- (magit-branch-set-face it)
- (propertize "pushRemote" 'face 'bold)))
- (--when-let (magit-get-@{push}-branch)
- (format "%s aka %s\n"
- (magit-branch-set-face it)
- (propertize "@{push}" 'face 'bold)))
- (format "using %s (%s is %s)\n"
- (propertize "git push" 'face 'bold)
- (propertize "push.default" 'face 'bold)
- (propertize default 'face 'bold))))))
-
-;;;###autoload
-(defun magit-push-to-remote (remote args)
- "Push to REMOTE without using an explicit refspec.
-The REMOTE is read in the minibuffer.
-
-This command simply runs \"git push -v [ARGS] REMOTE\". ARGS
-are the arguments specified in the popup buffer. No refspec
-arguments are used. Instead the behavior depends on at least
-these Git variables: `push.default', `remote.pushDefault',
-`branch.<branch>.pushRemote', `branch.<branch>.remote',
-`branch.<branch>.merge', and `remote.<remote>.push'.
-
-To add this command to the push popup add this to your init file:
-
- (with-eval-after-load \\='magit-remote
- (magit-define-popup-action \\='magit-push-popup ?r
- \\='magit-push-to-remote--desc
- \\='magit-push-to-remote ?p t))"
- (interactive (list (magit-read-remote "Push to remote")
- (magit-push-arguments)))
- (run-hooks 'magit-credential-hook)
- (magit-run-git-async "push" "-v" args remote))
-
-(defun magit-push-to-remote--desc ()
- (format "using %s\n" (propertize "git push <remote>" 'face 'bold)))
-
;;; Email
;;;###autoload (autoload 'magit-patch-popup "magit-remote" nil t)
diff --git a/lisp/magit.el b/lisp/magit.el
index 443dbc9..6770256 100644
--- a/lisp/magit.el
+++ b/lisp/magit.el
@@ -598,6 +598,10 @@ For X11 something like ~/.xinitrc should work.\n"
(require 'magit-sequence)
(require 'magit-commit)
(require 'magit-remote)
+ (require 'magit-clone)
+ (require 'magit-fetch)
+ (require 'magit-pull)
+ (require 'magit-push)
(require 'magit-bisect)
(require 'magit-stash)
(require 'magit-blame)