Fixing errors¶
Amend a commit¶
To amend the last commit:
$ #correct the errors, then
$ git add file
$ git commit --amend
$ # fix the commit message if necessary
To amend a past commit on a clean working directory, you need to come back to the erroneous commit, fix it and rebase: the latter commits on the the new fixed state.
An example adapted from user-manual: Rewriting a single commit
$ git log --stat -- badfile
$ git tag bad mywork~5
$ git checkout bad
$ # make changes here and update the index
$ git commit --amend
$ git rebase --onto HEAD bad mywork
$ git tag -d bad
The use of the tag is optional you can also do
$ BAD="7c2c66b71b"
$ git checkout $BAD
$ # make changes here and update the index
$ git commit --amend
$ git rebase --onto HEAD $BAD mywork
When you want to amend past commits with changes in the working tree, you cannot checkout the past commit because the worktree is dirty.
You can use git stash to come back to the original worktree or work in a linked temporary working directory:
$ git-new-workdir <repository> <temporary_workdir>
$ cd <temporary_workdir>
# find the commit to amend
$ git log --stat
$ BAD="<commit>"
$ git reset --hard $BAD
# edit the wrong file may be copying from <repository>
$ git add <changed file>
$ git commit --amend
$ git rebase --onto HEAD $BAD mywork
You can also use git rebase --interactive
as indicated
in the rebase section.
where you find an
example of fixing an old error with interactive rebase.
Commit a fixup and squash.¶
The interactive rebase can be made a lot
simpler for fixing errors with the git commit --fixup
or
git commit --squash command
.
On a clean worktree, or cleaned by a git stash
, you change your
erroneous file(s) and commit it (them) with
$ git commit --fixup=a0b1c2d3
Where you give the erroneous commit number, then you fixup the error with:
$ git rebase --interactive --autosquash a0b1c2d3^
The first command just use the original message prefixed by
fixup!
, the second one squash the original and next commit
discarding the message of the fixup commit.
You can also do a simple commit and begin your message by fixup!
followed by an initial section of the original commit message.
If instead of fixup you use squash the process is similar but the commit message for the folded commit is the concatenation of the messages of the first commit and of those with the squash command.
splitting a commit¶
ref: git-rebase: splitting commits, git gui
To split a commit, you first rebase interactively to the commit or one of its ancestor
$ git rebase -i <commit>
Then you mark the commit with the action edit, and when it comes to editing:
$ git reset HEAD^
Then you can examine the status with:
$ git status
and add some files and stage the appropriate hunks. It can be easy to use:
$ git gui
to commit the appropriate hunks in individual commits
Then you can as usual do:
$ git rebase --continue.