(make-nearby-temp-file "git-msg")))))
(when vc-git-patch-string
(unless (zerop (vc-git-command nil t nil "diff" "--cached" "--quiet"))
- (user-error "Index not empty"))
+ ;; Check that all staged changes also exist in the patch.
+ ;; This is needed to allow adding/removing files that are
+ ;; currently staged to the index. So remove the whole file diff
+ ;; from the patch because commit will take it from the index.
+ (with-temp-buffer
+ (vc-git-command (current-buffer) t nil "diff" "--cached")
+ (goto-char (point-min))
+ (let ((pos (point)) file-diff file-beg)
+ (while (not (eobp))
+ (forward-line 1) ; skip current "diff --git" line
+ (search-forward "diff --git" nil 'move)
+ (move-beginning-of-line 1)
+ (setq file-diff (buffer-substring pos (point)))
+ (if (and (setq file-beg (string-search
+ file-diff vc-git-patch-string))
+ ;; Check that file diff ends with an empty string
+ ;; or the beginning of the next file diff.
+ (string-match-p "\\`\\'\\|\\`diff --git"
+ (substring
+ vc-git-patch-string
+ (+ file-beg (length file-diff)))))
+ (setq vc-git-patch-string
+ (string-replace file-diff "" vc-git-patch-string))
+ (user-error "Index not empty"))
+ (setq pos (point))))))
(let ((patch-file (make-temp-file "git-patch")))
(with-temp-file patch-file
(insert vc-git-patch-string))