18

How can I make Git stash with untracked files, push it to patch and restore it in another computer.

git stash save -u feature
git stash show -p > patch
git apply patch

But path hasn't untracked files

ButuzGOL
  • 1,233
  • 2
  • 13
  • 27

1 Answers1

23

A normal git stash creates a stash bag that consists of two commits: the index, and the work-tree.

Using -u or -a (or their other spellings) creates a three-commit stash bag. The third commit contains (only) the untracked (-u) or untracked-and-ignored / "all" (-a) files, i.e., it omits all tracked files.

If you need this in the form of a patch, the trick is to create two patches:

  • changes to tracked files: git stash show -p (what you have so far), plus
  • the entire contents of the third commit, as a patch.

The easiest way to get the second bullet item is to git diff that third commit against an empty tree. Git always has an empty tree in every repository whose ID is the magic number 4b825dc642cb6eb9a060e54bf8d69288fbee4904. So a diff between that tree, and stash^3, will consist of a series of git patches that add the untracked files:

git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 stash^3

You can then simply combine the two patches into one:

git stash show -p > patch
git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 stash^3 >> patch

(See the last link above for a way to avoid hard-coding the magic number for the empty tree. Also, if you just want to view the u commit, use git show: git show stash^3, for instance.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • I do `git stash save --all` but when I do `git diff stash^3` zsh: no matches found: stash^3 If I understand right I need to make these three steps ? `git stash save --all` `git stash show -p > patch` `git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 stash^3 >> patch` – ButuzGOL Apr 03 '14 at 05:48
  • zsh is attempting to handle the `^3` itself, instead of passing it on to git. You must protect the `^` from zsh, with backslash or quotes, e.g., `'stash^3'` instead of just `stash^3`. (Different shells have different Special Characters, sh and bash don't need this.) – torek Apr 03 '14 at 05:54
  • Thanks just moved to zsh ) So after `git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 stash^3 >> patch` I get patch but also contains .gitignored files ? – ButuzGOL Apr 03 '14 at 06:16
  • Yes, because you used `--all` rather than `--untracked`. You can restore and drop that stash and make one with just `-u` if that's what you want instead. – torek Apr 03 '14 at 10:32
  • 1
    If you have trouble remembering the sha, just write it down on an index card and mumble it to yourself as you fall asleep each night. – xdhmoore Apr 27 '17 at 04:30
  • @xdhmoore: heh. Or, click on the link and see ways to compute it (my favorite is `git hash-object -t tree /dev/null`). – torek Apr 27 '17 at 06:09
  • I am still not seeing untracked files in the stash – Mathieu J. Sep 16 '18 at 19:23
  • @shigazaru: see my answer to [your other question](https://stackoverflow.com/q/52357450/1256452). – torek Sep 16 '18 at 19:39
  • 1
    To get only files / paths from a particular directory tree and pipe directly into `git apply`: `git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 stash^3 [] | git apply -` – AndOs Jul 31 '19 at 09:56
  • A little script: patchName="patch-`date +'%Y-%m-%d'_%H:%M:%S`"; git stash show -p >${patchName}; git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 stash^3 >>${patchName}; echo "${patchName}" – RedYeti May 18 '20 at 16:18