Function: vc-git--stash-staged-changes

vc-git--stash-staged-changes is a byte-compiled function defined in vc-git.el.gz.

Signature

(vc-git--stash-staged-changes FILES)

Documentation

Stash only the staged changes to FILES.

Source Code

;; Defined in /usr/src/emacs/lisp/vc/vc-git.el.gz
(defun vc-git--stash-staged-changes (files)
  "Stash only the staged changes to FILES."
  ;; This is necessary because even if you pass a list of file names
  ;; to 'git stash push', it will stash any and all staged changes.
  (unless (zerop
           (vc-git-command nil t files "diff" "--cached" "--quiet"))
    (cl-flet
        ((git-string (&rest args)
           (string-trim-right
            (with-output-to-string
              (apply #'vc-git-command standard-output 0 nil args)))))
      (let ((cached (make-nearby-temp-file "git-cached"))
            (message "Previously staged changes")
            tree)
        ;; Use a temporary index to create a tree object corresponding
        ;; to the staged changes to FILES.
        (unwind-protect
            (progn
              (with-temp-file cached
                (vc-git-command t 0 files "diff" "--cached" "--"))
              (let* ((index (make-nearby-temp-file "git-index"))
                     (process-environment
                      (cons (format "GIT_INDEX_FILE=%s" index)
                            process-environment)))
                (unwind-protect
                    (progn
                      (vc-git-command nil 0 nil "read-tree" "HEAD")
                      (vc-git-command nil 0 cached "apply" "--cached")
                      (setq tree (git-string "write-tree")))
                  (delete-file index))))
          (delete-file cached))
        ;; Prepare stash commit object, which has a special structure.
        (let* ((tree-commit (git-string "commit-tree" "-m" message
                                        "-p" "HEAD" tree))
               (stash-commit (git-string "commit-tree" "-m" message
                                         "-p" "HEAD" "-p" tree-commit
                                         tree)))
          ;; Push the new stash entry.
          (vc-git-command nil 0 nil "update-ref" "--create-reflog"
                          "-m" message "refs/stash" stash-commit)
          ;; Unstage the changes we've now stashed.
          (vc-git-command nil 0 files "reset" "--"))))))