17

I want to export one stash (the changes) that I see in my stash list in a .zip/.gz file. I have found the following command:

git stash show -p > patch

which saves the changes in a file, but I also want to keep .png files, etc... I am looking for a way to compress all of the changes contained in the stash in a file or a folder. Do you know any solution ?

Yassine Badache
  • 1,810
  • 1
  • 19
  • 38
epi4
  • 387
  • 1
  • 2
  • 15

3 Answers3

30

Try it with --binary option to export

git stash show -p --binary > changes.patch

When you want to import it, apply the patch

git apply changes.patch
Samuel Robert
  • 10,106
  • 7
  • 39
  • 60
9

While Samual Robert's answer does solve the stated problem, something to note:

git stash show will combine all staged and unstaged changes into a single patch, and will exclude untracked files even if you used git stash -u. By default git apply will make all of the changes in the patch into unstaged changes; you can make them staged by giving the --index option. But to preserve the distinction between staged and unstaged changes, or to include untracked files that are in the stash, you need to do something else.

A stash internally consists of two or three commits and some ref manipulation, so one option is to generate a patch from each commit and then reconstruct the stash manually on the other end. It takes a little trickery to get the right patches because of the way the commits are related.

git show stash^2 --binary >index.patch
git show stash^3 --binary >untracked.patch
git diff --binary stash^2 stash >wip.patch

Then on the receiving end

git apply index.patch
git add .
git apply wip.patch
git apply untracked.patch

Now the uncommitted state has been recreated on the other repo, and if you want you could re-stash it there.

If you need to materialize the change on the receiving end directly as a stash, without going through your worktree and index -- e.g. because the receiving side isn't in a "clean" state - you could do it using bundles. But there is a trick to making this work. On the source repo

git bundle create stash.bundle stash^..stash

On the receiving repo

git remote add bundle stash.bundle
git fetch stash:temp
git update-ref --create-reflog refs/stash temp
git branch -D temp

Note that we had to give an explicit refspec to get the stash ref out of the bundle. If we'd mapped it directly to refs/stash, then we can't count on a reflog entry being created - and without the reflog entry, it's not a usable stash. So instead we brought it in to a temporary branch, then used update-ref to create (or move) the stash ref and update the reflog.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
1

This approach ensures a smooth transfer of work between computers while maintaining the version history.

The trick is that we commit the changes, push to remote, pull on destincation, create a patch from commit, and then revert the commit. from there we apply the patch that contains our changes.


Remember to replace your_branch_name with actual BRANCH name.


Step 1: Commit Changes on Source Computer:

git add .
git commit -m "WIP"

Step 2: Push Changes to Remote:

git push origin your_branch_name

Step 3: Pull Changes on Destination Computer:

git pull origin your_branch_name

Step 4: Create a Patch from last commit that just pulled:

git checkout your_branch_name
git format-patch HEAD^ -o .
git add .
git stash save "Patch"

Step 5: Revert the WIP Commit:

git reset HEAD^
git add .
git commit -m "revert WIP"

Step 6: Pop Stash and Apply Patch:

git stash pop
git apply --ignore-space-change --ignore-whitespace  0001-wip.patch

This sequence of commands allows you to export changes from one computer to another using Git's version control features. It involves committing, pushing, pulling, generating a patch, stashing, reverting, and applying the changes.

akokani
  • 870
  • 8
  • 18