tags:

views:

49

answers:

2

Exposition:

  1. I do not git commit all that often; only after a lot of work.
  2. I occasionally do stupid things, like 'rm -f blah.hpp' when I mean 'rm -f blah.cpp'
  3. I use zsh
  4. I would like to set something up in my zsh precmd to do a "git add */; git commit -a -m 'auto log ...'"

Now, here's the issue: alot of these commits are spurious. At some future point (like 24 hours later), I would like to kill all these useless intermediate autocommits.

If your solution requires I slightly modify my git workflow -- that is okay. I am willing to introduce changes in order to have this autocommit setup.

+1  A: 

You want automatic "snapshot-style" commits which squash down once you have a true commit to make.

Here is my rough idea:

  1. Treat master as your "official" commit timeline and work in a feature branch. (This is a pretty orthodox workflow anyway.)
  2. Work in a so-called feature branch which takes automatic snapshots (via zsh precommand)
  3. When you are ready for a (human) commit, merge all the automatic snapshots from your feature branch into master with --squash and commit with an appropriate message.

This might require some aliases both in zsh and git but I think it could work. Here are some rough ideas, the key one being git merge --squash. (Also, sorry, I only speak Bash.)

# I type this manually when I start work in the morning.
start-snapshotting () {
    git checkout -b auto-snapshots master
    PROMPT_COMMAND=git-snapshot
}

git-snapshot () {
    branch=`git symbolic-ref HEAD`
    [ "$branch" = "refs/heads/auto-snapshots" ] || return 1

    git add . && \
    git status > /dev/null &&
    git commit -m 'Automatic snapshot'
}

# Do a real commit that I am interested in preserving.
# Parameters are passed unmodified to "git commit"
commit () {
    git checkout master && \
    git merge --squash auto-snapshots && \
    git commit "$@" && \
    git branch -D auto-snapshots && \
    git checkout -b auto-snapshots master
}

# I type this when I am done coding.
stop-snapshotting () {
    unset PROMPT_COMMAND
    git checkout master && \
    git branch -D auto-snapshots
}

Keep in mind there will be tons of edge cases such as files you should have added to .gitignore and I am sure plenty of others. But I think it could work.

jhs
A: 

With Git1.7:

  • you could make your auto-commit with a message beginning by fixup!
  • every 24h, you could do a git rebase --interactive --autosquash in order to squash all the automatic commits and ignoring their log messages.

See here for more details.

Of course, once in a while, do an explicit commit with a relevant message (for "real" commits") when you begin a task: all the other "automatic" commits will be squashed against that first commit;

VonC