This shows you the differences between two versions of the page.

Link to this comparison view

misc:git-stash [2018/08/14 11:25] (current)
Line 1: Line 1:
 +====== git reflog and git stash ======
 +A meta-repository that records — in the form of commits — every change you make to your repository.
 +This means that when you create a tree from your index and store it under a commit (all of which is done by commit), you are also, inadvertently adding that commit to the reflog, which can be viewed using the following command:
 +  $ git reflog ​  
 +  5f1bc85... HEAD@{0}: commit (initial): Initial commit  ​
 +The beauty of the reflog is that it persists independently of other changes in your repository.
 +This means I could unlink the above commit from my repository (using reset), yet it would still be referenced by the reflog for another 30 days, protecting it from garbage collection.
 +This gives you a month’s chance to recover the commit should you discover you really need it.
 +Another peculiarity of git is that it tracks also uncommited changes to your working tree. Let's say for example that you modiffied file ''​foo.c''​ in your working tree, that modification not being commited yet still exists in your file system, you can even see the hash for that modification using:
 +  $ git hash-object foo.c
 +  <some hash id>  ​
 +What does this do for you? Well, if you find yourself hacking away on your working tree and you reach the end of a long day, a good habit to get into is to stash away your changes: ​
 +  $ git stash
 +This takes all your directory’s contents—including both your working tree, and the state of the index — and creates blobs for them in the git repository, a tree to hold those blobs, and a pair of stash commits to hold the working tree and index and record the time when you did the stash.
 +This is a good practice because, although the next day you’ll just pull your changes back out of the stash with stash apply, you’ll have a reflog of all your stashed changes at the end of every day.
 +Here’s what you’d do after coming back to work the next morning (WIP here stands for “Work in progress”):​
 +  $ git stash list
 +  stash@{0}: WIP on master: 5f1bc85... Initial commit
 +  $ git reflog show stash # same output, plus the stash commit'​s hash id
 +  2add13e... stash@{0}: WIP on master: 5f1bc85... Initial commit
 +  $ git stash apply
 +Because your stashed working tree is stored under a commit, you can work with it like any other branch — at any time! This means you can view the log, see when you stashed it, and checkout any of your past working trees from the moment when you stashed them:
 +  $ git stash list
 +  stash@{0}: WIP on master: 73ab4c1... Initial commit
 +  ...
 +  stash@{32}: WIP on master: 5f1bc85... Initial commit
 +  $ git log stash@{32} ​                 # when did I do it?
 +  $ git show stash@{32} ​                # show me what I was working on
 +  $ git checkout -b temp stash@{32} ​    # let look at that old working tree!
 +This last command is particularly powerful: behold, I’m now playing around in an uncommitted working tree from over a month ago. I never even added those files to the index; I just used the simple expedient of calling stash before logging out each day, and stash apply when I logged back in. You could even automate these actions with //.login// and //.logout// scripts. If you ever want to clean up your stash list—say to keep only the last 30 days of activity— don’t use ''​stash clear'';​ use the ''​reflog expire''​ command instead:
 +  $ git stash clear            # DON'T! You'll lose all that history
 +  $ git reflog expire --expire=30.days refs/stash
 +  <outputs the stash bundles that'​ve been kept>
 +The beauty of stash is that it lets you apply unobtrusive version control to your working process itself: namely, the various stages of your working tree from day to day. You can even use //stash// on a regular basis if you like, with something like the following snapshot script:
 +  $ cat <<EOF > /​usr/​local/​bin/​git-snapshot
 +  #!/bin/sh
 +  git stash && git stash apply
 +  EOF
 +  $ chmod +x $_
 +  $ git snapshot
 +There’s no reason you couldn’t run this from a cron job every hour, along with running the ''​reflog expire''​ command every week or month.
  • misc/git-stash.txt
  • Last modified: 2018/08/14 11:25
  • (external edit)