Git workflow - fixing messed up commits
Sometimes you recognize that your change history is a bit of a mess. One commit contains multiple different types of changes, possibly even some refactoring.
In this post I describe my (current) workflow to handle that. Git being git, this might not be the only one, possibly not even the best way to do it!
First you need to know which commit is affected.
Last commit
If you happen to remember that the disastrous commit was the one you just did, you are in luck, as the process is quite easy.
git reset HEAD^- add the changes cleaner this time
- commit as required
- optional: stash other changes to run build/run tests
- repeat until working tree clean
Last commit~{>=1}
Old commits are a bit more tricky, as they require a rebase (you change the history). If you have not pushed the changes or are able to force push, that should not be a problem.
Finding out the commit
First of all we need to find out which commit is affected and how we can reference it exactly.
Usually it is sufficient to simply git log and find the hash, or at least an approximation of how many commits have happened since your critical change.
The three functions below are sufficient for the majority of the cases:
git logorgit log --onelineto find the commit by commit message onlygit log --statto find the commit by additionally checking the files affectedgit log -p -- ${FILENAME}to find all commits with changes of${FILENAME}(incl. diff)
Again, there are various different ways to describe a commit in git, but this is content for another post.
Changing the commit
Besides the rebase, we have the same workflow as for the last commit: 1
git rebase -i ${COMMIT_HASH}^, rebases from HEAD until the parent commit of${COMMIT_HASH}- vim/your editor opens showing all the commits since
${COMMIT_HASH}^ - mark
${COMMIT_HASH}asedit/e - apply same steps as if it were the last commit
git rebase --continue
In the first step you do not have to rebase all commits since the affected commit hash. As long as you define a range of commits in which the affected critical commit is in, you should be fine. Remember that the way rebasing works the history (incl. hashes) of all commits from your change on is going to be changed.