diff options
| -rw-r--r-- | default.mk | 4 | ||||
| -rw-r--r-- | lisp/Makefile | 4 | ||||
| -rw-r--r-- | lisp/magit-clone.el | 88 | ||||
| -rw-r--r-- | lisp/magit-fetch.el | 157 | ||||
| -rw-r--r-- | lisp/magit-merge.el | 2 | ||||
| -rw-r--r-- | lisp/magit-pull.el | 151 | ||||
| -rw-r--r-- | lisp/magit-push.el | 342 | ||||
| -rw-r--r-- | lisp/magit-remote.el | 611 | ||||
| -rw-r--r-- | lisp/magit.el | 4 |
9 files changed, 755 insertions, 608 deletions
@@ -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) |
