简体   繁体   中英

Automatically stashing

The section Last links in the chain: Stashing and the reflog in http://ftp.newartisans.com/pub/git.from.bottom.up.pdf recommends stashing often to take snapshots of your work in progress. The author goes as far as recommending that you can use a cron job to stash your work regularly, without having to do a stash manually.

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.

The problem with this approach is:

  1. If there are no changes to your working copy, the "git stash apply" will cause your last stash to be applied over your working copy.
  2. There could be race conditions between when the cron job executes and the user working on the working copy. For example, "git stash" runs, then the user opens the file, then the script's "git stash apply" is executed.

Does anybody have suggestions for making this automatic stashing work more reliably?

I certainly wouldn't set up automatic stashing as described in that (otherwise excellent) article, for exactly the reasons you cite.

I prefer to use the stash as it is intended to be used, where I deliberately stash and apply changes as I'm working. For periodic backups, I use a proper backup solution. In my opinion, Git is not a substitute for a backup solution.

git stash is actually just a little shell script that creates a commit which is not referenced in any branch. You could emulate this behaviour without race conditions:

#!/bin/sh
GIT_DIR=$(git rev-parse --git-dir) || exit
ref_stash=refs/stash

w_commit=$(git stash create) # creates a commit for the wip

# gather some info
head=$(git log --no-color --abbrev-commit --pretty=oneline -n 1 HEAD --)
branch=$(git symbolic-ref -q HEAD)
branch=${branch#refs/heads/}
msg=$(printf 'WIP on %s: %s' "$branch" "$head")

# Make sure the reflog for stash is kept.
: >>"$GIT_DIR/logs/$ref_stash"

git update-ref -m "$msg" $ref_stash $w_commit

The script may need some polishing but I hope you get the idea :)

For my personnal use (working with that during 3 years), I have added this line in the alias config section:

s = !sh -c \"git stash save | grep 'No local changes to save' && git $* || (git $* && git stash pop) \"

Then, I can run every git command with auto stashing just by adding a 's' before. Like that in your case : git s snaspshot

Perhaps too late but hope it will help someone, one day...

我更喜欢在藏匿管理之前进行分支管理:看看这里

For backing things up I'd recommend online backup service, similar to dropbox.com You literally don't need to do anything, it just tracks all the changes you make during the day for you.

I have it enabled for all my git repositories which just helps me focus on the actual task at hand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM