Commit 334ce5c7 authored by Jonas Bernoulli's avatar Jonas Bernoulli

avoid needlessly reverting file-visiting buffers

After running a git command known not to change the work tree,
do not attempt to revert file-visiting buffers.

Re #1807.
parent f0de7aaf
......@@ -103,16 +103,17 @@ With a prefix argument and if necessary, attempt a 3-way merge."
(interactive)
(--when-let (magit-current-section)
(magit-maybe-backup)
(pcase (list (magit-diff-type) (magit-diff-scope))
(`(untracked ,_) (magit-stage-untracked))
(`(unstaged region) (magit-apply-region it "--cached"))
(`(unstaged hunk) (magit-apply-hunk it "--cached"))
(`(unstaged file) (magit-run-git "add" "-u" "--" (magit-section-value it)))
(`(unstaged files) (magit-run-git "add" "-u" "--" (magit-region-values)))
(`(unstaged list) (magit-run-git "add" "-u" "."))
(`(staged ,_) (user-error "Already staged"))
(`(committed ,_) (user-error "Cannot stage committed changes"))
(`(undefined ,_) (user-error "Cannot stage this change")))))
(let ((inhibit-magit-revert t))
(pcase (list (magit-diff-type) (magit-diff-scope))
(`(untracked ,_) (magit-stage-untracked))
(`(unstaged region) (magit-apply-region it "--cached"))
(`(unstaged hunk) (magit-apply-hunk it "--cached"))
(`(unstaged file) (magit-run-git "add" "-u" "--" (magit-section-value it)))
(`(unstaged files) (magit-run-git "add" "-u" "--" (magit-region-values)))
(`(unstaged list) (magit-run-git "add" "-u" "."))
(`(staged ,_) (user-error "Already staged"))
(`(committed ,_) (user-error "Cannot stage committed changes"))
(`(undefined ,_) (user-error "Cannot stage this change"))))))
;;;###autoload
(defun magit-stage-file (file)
......@@ -131,7 +132,7 @@ requiring confirmation."
nil t nil nil default)
default))))
(magit-maybe-backup)
(magit-run-git "add" file))
(magit-run-git-no-revert "add" file))
;;;###autoload
(defun magit-stage-modified (&optional all)
......@@ -146,7 +147,7 @@ ignored) files.
(user-error "Abort"))
(list current-prefix-arg)))
(magit-maybe-backup)
(magit-run-git "add" (if all "--all" "--update") "."))
(magit-run-git-no-revert "add" (if all "--all" "--update") "."))
(defun magit-stage-untracked ()
(let ((section (magit-current-section)) files repos)
......@@ -173,19 +174,20 @@ ignored) files.
(interactive)
(--when-let (magit-current-section)
(magit-maybe-backup)
(pcase (list (magit-diff-type) (magit-diff-scope))
(`(untracked ,_) (user-error "Cannot unstage untracked changes"))
(`(unstaged ,_) (user-error "Already unstaged"))
(`(staged region) (magit-apply-region it "--reverse" "--cached"))
(`(staged hunk) (magit-apply-hunk it "--reverse" "--cached"))
(`(staged file) (magit-unstage-1 (magit-section-value it)))
(`(staged files) (magit-unstage-1 (magit-region-values)))
(`(staged list) (when (or (and (not (magit-anything-unstaged-p))
(not (magit-untracked-files)))
(magit-confirm 'unstage-all-changes))
(magit-run-git "reset" "HEAD" "--")))
(`(committed ,_) (user-error "Cannot unstage committed changes"))
(`(undefined ,_) (user-error "Cannot unstage this change")))))
(let ((inhibit-magit-revert t))
(pcase (list (magit-diff-type) (magit-diff-scope))
(`(untracked ,_) (user-error "Cannot unstage untracked changes"))
(`(unstaged ,_) (user-error "Already unstaged"))
(`(staged region) (magit-apply-region it "--reverse" "--cached"))
(`(staged hunk) (magit-apply-hunk it "--reverse" "--cached"))
(`(staged file) (magit-unstage-1 (magit-section-value it)))
(`(staged files) (magit-unstage-1 (magit-region-values)))
(`(staged list) (when (or (and (not (magit-anything-unstaged-p))
(not (magit-untracked-files)))
(magit-confirm 'unstage-all-changes))
(magit-run-git "reset" "HEAD" "--")))
(`(committed ,_) (user-error "Cannot unstage committed changes"))
(`(undefined ,_) (user-error "Cannot unstage this change"))))))
;;;###autoload
(defun magit-unstage-file (file)
......@@ -203,7 +205,8 @@ without requiring confirmation."
nil t nil nil default)
default))))
(magit-maybe-backup)
(magit-unstage-1 file))
(let ((inhibit-magit-revert t))
(magit-unstage-1 file)))
(defun magit-unstage-1 (args)
(if (magit-no-commit-p)
......
......@@ -246,7 +246,7 @@ depending on the value of option `magit-commit-squash-confirm'.
((and (magit-rebase-in-progress-p)
(not (magit-anything-unstaged-p))
(y-or-n-p "Nothing staged. Continue in-progress rebase? "))
(magit-run-git-with-editor "rebase" "--continue")
(magit-run-git-sequencer "rebase" "--continue")
nil)
((and (file-exists-p (magit-git-dir "MERGE_MSG"))
(not (magit-anything-unstaged-p)))
......
......@@ -453,6 +453,7 @@ the buffer. Finally reset the window configuration to nil."
;;; Refresh Machinery
(defvar inhibit-magit-refresh nil)
(defvar inhibit-magit-revert nil)
(defun magit-refresh ()
"Refresh some buffers belonging to the current repository.
......@@ -533,11 +534,11 @@ Uses the buffer-local `magit-refresh-function'."
(defun magit-revert-buffers (&optional force)
"Revert unmodified file-visiting buffers of the current repository.
If, and only if, the global `magit-auto-revert-mode' is turned
on, or if optional FORCE is non-nil, revert all unmodified
buffers that visit files being tracked in the current
repository."
(when (or force magit-auto-revert-mode)
If, and only if, the global `magit-auto-revert-mode' is turned on
and `inhibit-magit-revert' is nil; or if optional FORCE is non-nil,
then revert all unmodified buffers that visit files being tracked
in the current repository."
(when (or force (and magit-auto-revert-mode (not inhibit-magit-revert)))
(-when-let (topdir (magit-toplevel-safe))
(let ((tracked (magit-revision-files "HEAD"))
(buffers (buffer-list)))
......
......@@ -43,6 +43,8 @@
(require 'autorevert)
(defvar magit-status-buffer-name-format)
(eval-when-compile (require 'dired))
(declare-function dired-uncache 'dired)
......@@ -198,6 +200,24 @@ variable `magit-process-buffer-name-format'."
(magit-call-git args)
(magit-refresh))
(defun magit-run-git-no-revert (&rest args)
"Call Git synchronously in a separate process, and refresh.
Option `magit-git-executable' specifies the Git executable and
option `magit-git-standard-options' specifies constant arguments.
The arguments ARGS specify arguments to Git, they are flattened
before use.
After Git returns, the current buffer (if it is a Magit buffer)
as well as the current repository's status buffer are refreshed.
File-visiting buffers are *not* reverted, regardless of whether
`magit-auto-revert-mode' is active or not.
Process output goes into a new section in a buffer specified by
variable `magit-process-buffer-name-format'."
(let ((inhibit-magit-revert t))
(magit-run-git args)))
(defun magit-call-git (&rest args)
"Call Git synchronously in a separate process.
......@@ -281,6 +301,22 @@ See `magit-start-process' for more information."
(mapconcat 'identity (-flatten args) " "))
(magit-start-git nil args))
(defun magit-run-git-async-no-revert (&rest args)
"Start Git, prepare for refresh, and return the process object.
ARGS is flattened and then used as arguments to Git.
Display the command line arguments in the echo area.
After Git returns some buffers are refreshed: the buffer that was
current when this function was called (if it is a Magit buffer
and still alive), as well as the respective Magit status buffer.
File-visiting buffers are *not* reverted, regardless of whether
`magit-auto-revert-mode' is active or not.
See `magit-start-process' for more information."
(let ((inhibit-magit-revert t))
(magit-run-git-async args)))
(defun magit-run-git-with-editor (&rest args)
"Export GIT_EDITOR and start Git.
Also prepare for refresh and return the process object.
......@@ -291,13 +327,37 @@ Display the command line arguments in the echo area.
After Git returns some buffers are refreshed: the buffer that was
current when this function was called (if it is a Magit buffer
and still alive), as well as the respective Magit status buffer.
File-visiting buffers are *not* reverted, regardless of whether
`magit-auto-revert-mode' is active or not.
See `magit-start-process' and `with-editor' for more information."
(with-editor "GIT_EDITOR"
(let ((magit-process-popup-time -1)
(inhibit-magit-revert nil))
(magit-run-git-async args))))
(defun magit-run-git-sequencer (&rest args)
"Export GIT_EDITOR and start Git.
Also prepare for refresh and return the process object.
ARGS is flattened and then used as arguments to Git.
Display the command line arguments in the echo area.
After Git returns some buffers are refreshed: the buffer that was
current when this function was called (if it is a Magit buffer
and still alive), as well as the respective Magit status buffer.
If the sequence stops at a commit, make the section representing
that commit the current section by moving `point' there.
Unmodified buffers visiting files that are tracked in the current
repository are reverted if `magit-auto-revert-mode' is active.
See `magit-start-process' and `with-editor' for more information."
(with-editor "GIT_EDITOR"
(let ((magit-process-popup-time -1))
(magit-run-git-async args))))
(magit-run-git-async args)))
(set-process-sentinel magit-this-process #'magit-sequencer-process-sentinel)
magit-this-process)
(defun magit-start-git (input &rest args)
"Start Git, prepare for refresh, and return the process object.
......@@ -359,6 +419,8 @@ tracked in the current repository are reverted if
(process-put process 'default-dir default-directory)
(when inhibit-magit-refresh
(process-put process 'inhibit-refresh t))
(when inhibit-magit-revert
(process-put process 'inhibit-revert t))
(setf (magit-section-process section) process)
(with-current-buffer process-buf
(set-marker (process-mark process) (point)))
......@@ -446,7 +508,29 @@ tracked in the current repository are reverted if
(process-get process 'command-buf))
(when (buffer-live-p it)
(with-current-buffer it
(magit-refresh)))))))
(let ((inhibit-magit-revert (process-get process 'inhibit-revert)))
(magit-refresh))))))))
(defun magit-sequencer-process-sentinel (process event)
"Special sentinel used by `magit-run-git-sequencer'."
(when (memq (process-status process) '(exit signal))
(magit-process-sentinel process event)
(--when-let (magit-mode-get-buffer
magit-status-buffer-name-format
'magit-status-mode)
(with-current-buffer it
(--when-let
(magit-get-section
`((commit . ,(magit-rev-parse "HEAD"))
(,(pcase (car (cadr (-split-at
(1+ (length magit-git-standard-options))
(process-command process))))
((or "rebase" "am") 'rebase-sequence)
((or "cherry-pick" "revert") 'sequence)))
(status)))
(goto-char (magit-section-start it))
(magit-section-update-highlight))))))
(defun magit-process-filter (proc string)
"Default filter used by `magit-start-process'."
......
......@@ -110,20 +110,20 @@ then read the remote."
(interactive (list (or (magit-get-remote)
(magit-read-remote "Fetch remote"))
(magit-fetch-arguments)))
(magit-run-git-async "fetch" remote args))
(magit-run-git-async-no-revert "fetch" remote args))
;;;###autoload
(defun magit-fetch (remote &optional args)
"Fetch from another repository."
(interactive (list (magit-read-remote "Fetch remote")
(magit-fetch-arguments)))
(magit-run-git-async "fetch" remote args))
(magit-run-git-async-no-revert "fetch" remote args))
;;;###autoload
(defun magit-fetch-all (&optional args)
"Fetch from another repository."
(interactive (list (magit-fetch-arguments)))
(magit-run-git-async "remote" "update" args))
(magit-run-git-async-no-revert "remote" "update" args))
;;; Pull
......@@ -188,10 +188,11 @@ If the upstream isn't set, then read the remote branch."
"Push a branch to its upstream branch.
If the upstream isn't set, then read the remote branch."
(interactive (magit-push-read-args t))
(magit-run-git-async "push" "-v" args remote
(if remote-branch
(format "%s:refs/heads/%s" branch remote-branch)
branch)))
(magit-run-git-async-no-revert
"push" "-v" args remote
(if remote-branch
(format "%s:refs/heads/%s" branch remote-branch)
branch)))
;;;###autoload
(defun magit-push-elsewhere (branch remote remote-branch &optional args)
......@@ -234,7 +235,7 @@ 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)))
(magit-run-git-async "push" remote "--tags" args))
(magit-run-git-async-no-revert "push" remote "--tags" args))
;;;###autoload
(defun magit-push-tag (tag remote &optional args)
......@@ -242,7 +243,7 @@ branch as default."
(interactive
(let ((tag (magit-read-tag "Push tag")))
(list tag (magit-read-remote (format "Push %s to remote" tag) nil t))))
(magit-run-git-async "push" remote tag))
(magit-run-git-async-no-revert "push" remote tag))
;;; Email
......@@ -279,7 +280,7 @@ branch as default."
range
(format "%s~..%s" range range))))
(magit-patch-arguments)))
(magit-run-git "format-patch" range args))
(magit-run-git-no-revert "format-patch" range args))
;;;###autoload
(defun magit-request-pull (url start end)
......@@ -298,7 +299,8 @@ is asked to pull. START has to be reachable from that commit."
(compose-mail)
(setq default-directory dir))
(message-goto-body)
(magit-git-insert "request-pull" start url)
(let ((inhibit-magit-revert t))
(magit-git-insert "request-pull" start url))
(set-buffer-modified-p nil))
;;; magit-remote.el ends soon
......
......@@ -76,37 +76,6 @@
;;; Common
(defun magit-run-git-sequencer (&rest args)
"Call Git synchronously in a separate process, and refresh.
This is like `magit-run-git-with-editor' (which see) except that
the process sentinel is `magit-sequencer-process-sentinel'."
(apply #'magit-run-git-with-editor args)
(set-process-sentinel magit-this-process #'magit-sequencer-process-sentinel)
magit-this-process)
(defun magit-sequencer-process-sentinel (process event)
"Process sentinel used when running sequence commands.
Run the regular `magit-process-sentinel' and then, if the
sequence stops at a commit, make the section representing
that commit the current section by moving `point' there."
(when (memq (process-status process) '(exit signal))
(magit-process-sentinel process event)
(--when-let (magit-mode-get-buffer
magit-status-buffer-name-format
'magit-status-mode)
(with-current-buffer it
(--when-let
(magit-get-section
`((commit . ,(magit-rev-parse "HEAD"))
(,(pcase (car (cadr (-split-at
(1+ (length magit-git-standard-options))
(process-command process))))
((or "rebase" "am") 'rebase-sequence)
((or "cherry-pick" "revert") 'sequence)))
(status)))
(goto-char (magit-section-start it))
(magit-section-update-highlight))))))
;;;###autoload
(defun magit-sequencer-continue ()
"Resume the current cherry-pick or revert sequence."
......
......@@ -1002,7 +1002,7 @@ changes.
"Create BRANCH at branch or revision START-POINT.
\n(git branch [ARGS] BRANCH START-POINT)."
(interactive (magit-branch-read-args "Create branch"))
(magit-run-git "branch" args branch start-point))
(magit-run-git-no-revert "branch" args branch start-point))
;;;###autoload
(defun magit-branch-and-checkout (branch start-point &optional args)
......@@ -1097,13 +1097,14 @@ defaulting to the branch at point."
"Change upstream to branch"
(delete branch (magit-list-branch-names))
nil nil nil 'magit-revision-history))))
(magit-run-git "branch" (concat "--set-upstream-to=" upstream) branch))
(magit-run-git-no-revert "branch" (concat "--set-upstream-to=" upstream)
branch))
;;;###autoload
(defun magit-branch-unset-upstream (branch)
"Unset the upstream branch of BRANCH."
(interactive (list (magit-read-local-branch "Unset upstream of branch")))
(magit-run-git "branch" "--unset-upstream" branch))
(magit-run-git-no-revert "branch" "--unset-upstream" branch))
;;;###autoload
(defun magit-branch-rename (old new &optional force)
......@@ -1116,7 +1117,7 @@ With prefix, forces the rename even if NEW already exists.
(magit-read-string (format "Rename branch '%s' to" branch))
current-prefix-arg)))
(unless (string= old new)
(magit-run-git "branch" (if force "-M" "-m") old new)))
(magit-run-git-no-revert "branch" (if force "-M" "-m") old new)))
;;;###autoload
(defun magit-branch-edit-description (branch)
......@@ -1185,7 +1186,9 @@ edit it.
(interactive (list (magit-read-other-branch-or-commit "Merge")
(magit-merge-arguments)))
(magit-merge-assert)
(magit-run-git-with-editor "merge" "--edit" args rev))
(with-editor "GIT_EDITOR"
(let ((magit-process-popup-time -1))
(magit-run-git-async "merge" "--edit" args rev))))
;;;###autoload
(defun magit-merge-nocommit (rev &optional args)
......@@ -1453,7 +1456,7 @@ defaulting to the tag at point.
(interactive (list (--if-let (magit-region-values 'tag)
(magit-confirm t nil "Delete %i tags" it)
(magit-read-tag "Delete tag" t))))
(magit-run-git "tag" "-d" tags))
(magit-run-git-no-revert "tag" "-d" tags))
(defun magit-tag-prune (tags remote-tags remote)
"Offer to delete tags missing locally from REMOTE, and vice versa."
......@@ -1475,9 +1478,10 @@ defaulting to the tag at point.
(setq rtags nil))
(list ltags rtags remote)))
(when tags
(magit-run-git "tag" "-d" tags))
(magit-call-git "tag" "-d" tags))
(when remote-tags
(magit-run-git-async "push" remote (--map (concat ":" it) remote-tags))))
(magit-run-git-async-no-revert
"push" remote (--map (concat ":" it) remote-tags))))
;;;; Notes
......@@ -1573,12 +1577,12 @@ of Git's `note' command, default to operate on that ref."
it)))
current-prefix-arg))
(if ref
(magit-run-git "config" (and global "--global") "core.notesRef"
(if (string-prefix-p "refs/" ref)
ref
(concat "refs/notes/" ref)))
(magit-run-git "config" (and global "--global")
"--unset" "core.notesRef")))
(magit-run-git-no-revert "config" (and global "--global") "core.notesRef"
(if (string-prefix-p "refs/" ref)
ref
(concat "refs/notes/" ref)))
(magit-run-git-no-revert "config" (and global "--global")
"--unset" "core.notesRef")))
(defun magit-notes-set-display-refs (refs &optional global)
"Set notes refs to be display in addition to \"core.notesRef\".
......@@ -1602,7 +1606,8 @@ the current repository."
(magit-git-success "config" "--unset-all" global "notes.displayRef")
(dolist (ref refs)
(magit-call-git "config" "--add" global "notes.displayRef" ref))
(magit-refresh))
(let ((inhibit-magit-revert t))
(magit-refresh)))
(defun magit-notes-read-args (prompt)
(list (magit-read-branch-or-commit prompt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment