Saturday, January 14, 2012

Making interim commits in git

I'm reading the Git Book and wondering about a habit that I have in using version control (so far, subversion).

I like to make commits only for working, at least compiling, stuff. But I also want to make them as "fallbacks" in the middle of bigger changes, in case things start going in a bad direction. In svn, I mark these commits as "interim" by their comment.

That works well with subversion. The commits end up in the repository, but there's no real harm in that. Svn stores deltas, so there will be the changes from A to interim (to 2nd interim, ...) to B. Not much different from having changes directly from A to B. No downside.

Git, however, stores the whole binary "blob" of a file in a commit. Anything that's changed. Moreover, I wouldn't really even want to get the interim commits all the way to the repo. I would simply want to have a temporary "level of undo" where I can fall back.

I will now keep an eye open for a solution using git that would allow this. Something like:

- start working on new change
- make "interim" commits
- once ready (things compile, and run, and the undos won't be required): purge the interim commits
- make one real commit that contains all the changes (A to B)
- git push

If anyone already knows how to do this, I'd be interested. If not, I will try to figure it out.

If it *cannot* be done with git, I think the system would benefit of such an addition (ability to merge commits that haven't been pushed into a single one, removing the blobs that aren't being referred to any more after the merge).



jannek said...

I would go the rebase path:

- tinker
- make interim commit
- ...
- feeling ready to push out: git log to find the "distance" between HEAD and your last real commit, let it be 3 commits here
- "git rebase -i HEAD~3" and squash them together as you see to fit

See and for more info.

Asko K. said...

Thanks, Janne. Rebase and squashing really seems to be the answer. Still 100 pages further down the Git book I'm reading. Did a peek for this! :)

(and I thought I'd found a downside in Git. Nah. It's perfect. :P)

jannek said...

Only possible pitfall is the case that you've accidentally already pushed some of your interim commits. Then you're changing (public) history and might be in trouble. Mercurial has very handy "incoming" and "outgoing" commands, previewing what's about to go in or out without actually changing anything.

Asko K. said...

Well, we could make a push hook or something that disallows a push that would include a commit with the message "interim". Anyways, it's not an acute problem - just something I was curious to see whether it can be done with Git. And it Can. :) Thanks.