Skip to content

Commit 0520e21

Browse files
julliardgitster
authored andcommitted
git.el: Better handling of subprocess errors.
Where possible, capture the output of the git command and display it if the command fails. Signed-off-by: Alexandre Julliard <julliard@winehq.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 928323a commit 0520e21

File tree

1 file changed

+51
-37
lines changed

1 file changed

+51
-37
lines changed

contrib/emacs/git.el

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
;;
3636
;; TODO
3737
;; - portability to XEmacs
38-
;; - better handling of subprocess errors
3938
;; - diff against other branch
4039
;; - renaming files from the status buffer
4140
;; - creating tags
@@ -191,6 +190,18 @@ if there is already one that displays the same directory."
191190
(append (git-get-env-strings env) (list "git") args))
192191
(apply #'call-process "git" nil buffer nil args)))
193192

193+
(defun git-call-process-display-error (&rest args)
194+
"Wrapper for call-process that displays error messages."
195+
(let* ((dir default-directory)
196+
(buffer (get-buffer-create "*Git Command Output*"))
197+
(ok (with-current-buffer buffer
198+
(let ((default-directory dir)
199+
(buffer-read-only nil))
200+
(erase-buffer)
201+
(eq 0 (apply 'call-process "git" nil (list buffer t) nil args))))))
202+
(unless ok (display-message-or-buffer buffer))
203+
ok))
204+
194205
(defun git-call-process-env-string (env &rest args)
195206
"Wrapper for call-process that sets environment strings,
196207
and returns the process output as a string."
@@ -377,7 +388,7 @@ and returns the process output as a string."
377388
(when reason
378389
(push reason args)
379390
(push "-m" args))
380-
(eq 0 (apply #'git-call-process-env nil nil "update-ref" args))))
391+
(apply 'git-call-process-display-error "update-ref" args)))
381392

382393
(defun git-read-tree (tree &optional index-file)
383394
"Read a tree into the index file."
@@ -866,16 +877,17 @@ Return the list of files that haven't been handled."
866877
(if (or (not (string-equal tree head-tree))
867878
(yes-or-no-p "The tree was not modified, do you really want to perform an empty commit? "))
868879
(let ((commit (git-commit-tree buffer tree head)))
869-
(condition-case nil (delete-file ".git/MERGE_HEAD") (error nil))
870-
(condition-case nil (delete-file ".git/MERGE_MSG") (error nil))
871-
(with-current-buffer buffer (erase-buffer))
872-
(git-update-status-files (git-get-filenames files) 'uptodate)
873-
(git-call-process-env nil nil "rerere")
874-
(git-call-process-env nil nil "gc" "--auto")
875-
(git-refresh-files)
876-
(git-refresh-ewoc-hf git-status)
877-
(message "Committed %s." commit)
878-
(git-run-hook "post-commit" nil))
880+
(when commit
881+
(condition-case nil (delete-file ".git/MERGE_HEAD") (error nil))
882+
(condition-case nil (delete-file ".git/MERGE_MSG") (error nil))
883+
(with-current-buffer buffer (erase-buffer))
884+
(git-update-status-files (git-get-filenames files) 'uptodate)
885+
(git-call-process-env nil nil "rerere")
886+
(git-call-process-env nil nil "gc" "--auto")
887+
(git-refresh-files)
888+
(git-refresh-ewoc-hf git-status)
889+
(message "Committed %s." commit)
890+
(git-run-hook "post-commit" nil)))
879891
(message "Commit aborted."))))
880892
(message "No files to commit.")))
881893
(delete-file index-file))))))
@@ -986,9 +998,9 @@ Return the list of files that haven't been handled."
986998
;; FIXME: add support for directories
987999
(unless files
9881000
(push (file-relative-name (read-file-name "File to add: " nil nil t)) files))
989-
(apply #'git-call-process-env nil nil "update-index" "--add" "--" files)
990-
(git-update-status-files files 'uptodate)
991-
(git-success-message "Added" files)))
1001+
(when (apply 'git-call-process-display-error "update-index" "--add" "--" files)
1002+
(git-update-status-files files 'uptodate)
1003+
(git-success-message "Added" files))))
9921004

9931005
(defun git-ignore-file ()
9941006
"Add marked file(s) to the ignore list."
@@ -1014,9 +1026,9 @@ Return the list of files that haven't been handled."
10141026
(if (file-directory-p name)
10151027
(delete-directory name)
10161028
(delete-file name))))
1017-
(apply #'git-call-process-env nil nil "update-index" "--remove" "--" files)
1018-
(git-update-status-files files nil)
1019-
(git-success-message "Removed" files))
1029+
(when (apply 'git-call-process-display-error "update-index" "--remove" "--" files)
1030+
(git-update-status-files files nil)
1031+
(git-success-message "Removed" files)))
10201032
(message "Aborting"))))
10211033

10221034
(defun git-revert-file ()
@@ -1034,28 +1046,30 @@ Return the list of files that haven't been handled."
10341046
('unmerged (push (git-fileinfo->name info) modified))
10351047
('modified (push (git-fileinfo->name info) modified))))
10361048
;; check if a buffer contains one of the files and isn't saved
1037-
(dolist (file (append added modified))
1049+
(dolist (file modified)
10381050
(let ((buffer (get-file-buffer file)))
10391051
(when (and buffer (buffer-modified-p buffer))
10401052
(error "Buffer %s is modified. Please kill or save modified buffers before reverting." (buffer-name buffer)))))
1041-
(when added
1042-
(apply #'git-call-process-env nil nil "update-index" "--force-remove" "--" added))
1043-
(when modified
1044-
(apply #'git-call-process-env nil nil "checkout" "HEAD" modified))
1045-
(git-update-status-files (append added modified) 'uptodate)
1046-
(dolist (file (append added modified))
1047-
(let ((buffer (get-file-buffer file)))
1048-
(when buffer (with-current-buffer buffer (revert-buffer t t t)))))
1049-
(git-success-message "Reverted" (git-get-filenames files)))))
1053+
(let ((ok (and
1054+
(or (not added)
1055+
(apply 'git-call-process-display-error "update-index" "--force-remove" "--" added))
1056+
(or (not modified)
1057+
(apply 'git-call-process-display-error "checkout" "HEAD" modified)))))
1058+
(git-update-status-files (append added modified) 'uptodate)
1059+
(when ok
1060+
(dolist (file modified)
1061+
(let ((buffer (get-file-buffer file)))
1062+
(when buffer (with-current-buffer buffer (revert-buffer t t t)))))
1063+
(git-success-message "Reverted" (git-get-filenames files)))))))
10501064

10511065
(defun git-resolve-file ()
10521066
"Resolve conflicts in marked file(s)."
10531067
(interactive)
10541068
(let ((files (git-get-filenames (git-marked-files-state 'unmerged))))
10551069
(when files
1056-
(apply #'git-call-process-env nil nil "update-index" "--" files)
1057-
(git-update-status-files files 'uptodate)
1058-
(git-success-message "Resolved" files))))
1070+
(when (apply 'git-call-process-display-error "update-index" "--" files)
1071+
(git-update-status-files files 'uptodate)
1072+
(git-success-message "Resolved" files)))))
10591073

10601074
(defun git-remove-handled ()
10611075
"Remove handled files from the status list."
@@ -1320,12 +1334,12 @@ amended version of it."
13201334
(when (git-empty-db-p) (error "No commit to amend."))
13211335
(let* ((commit (git-rev-parse "HEAD"))
13221336
(files (git-get-commit-files commit)))
1323-
(git-call-process-env nil nil "reset" "--soft" "HEAD^")
1324-
(git-update-status-files (copy-sequence files) 'uptodate)
1325-
(git-mark-files git-status files)
1326-
(git-refresh-files)
1327-
(git-setup-commit-buffer commit)
1328-
(git-commit-file)))
1337+
(when (git-call-process-display-error "reset" "--soft" "HEAD^")
1338+
(git-update-status-files (copy-sequence files) 'uptodate)
1339+
(git-mark-files git-status files)
1340+
(git-refresh-files)
1341+
(git-setup-commit-buffer commit)
1342+
(git-commit-file))))
13291343

13301344
(defun git-find-file ()
13311345
"Visit the current file in its own buffer."

0 commit comments

Comments
 (0)