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
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¶
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.
I repeat a warning so often given, so often forgot : Keep a copy of your repository before making any destructive change on the repository internals.
It can happen that a repository become corrupted. When doing any operation that check the repo structure, often when trying to commit, you have this error:
error: invalid object 100644 db4f06caa1f321c01c667572f08449e8ebfc0713 for 'mystory.txt'
When you do a structure check in the repo you have:
$ git fsck --full Checking object directories: 100% (256/256), done. Checking objects: 100% (7448/7448), done. dangling commit e733d3ed3e27725db037078e56006c54fe3b6095 dangling commit 35b7ea4d2648bd3d2cbfeaf90d2ddb0742211517 dangling commit 323ebd233c5fa597cbd354ffae1ecc30643605ad missing blob db4f06caa1f321c01c667572f08449e8ebfc0713 dangling commit bb5152e989824799cc7a0de8e4753b411c17feb5 dangling commit 90d7899f21ec19abdc59764162a4161a7e9451f8
The dangling commits are not an error, there are just objects that are not in any branch, may be because you have rebased, after some time they will go away during a garbage collect.
The missing blob imply that the named blob is neither in
.git/objects/ namely with this hash in
or in a pack inside
.git/objects/pack there are two ways of fixing
it either find it in another repo or recreate it.
To find the object in a copy of your repo you can also look at the
objects/d4/ repo; but it it gives only loose object that are not
yet packed. You can see the blobs in a pack by:
$ git show-index .git/objects/pack/pack-ef11586b8de074c2b62c5a148b16096806adeb1c.idx | cut -f 2 -d ' '
$ git verify-pack -v .git/objects/pack/pack-ef11586b8de074c2b62c5a148b16096806adeb1c.idx |\ grep ' blob ' | cut -f 1 -d ' '
but if you just want to check if the pack contains your object:
$ git show-index .git/objects/pack/pack-ef11586b8de074c2b62c5a148b16096806adeb1c.idx |\ grep db4f06caa1f321c01c667572f08449e8ebfc0713
Then you can unpack the pack to make the object loose again by moving the pack out of the repo and issuing:
$ git unpack-objects < .git/objects/pack/pack-ef11586b8de074c2b62c5a148b16096806adeb1c.pack
If the pack is corrupt you need to add the
If you don’t succeed to find a copy of the missing object there is an other way, that is to recreate the object. I will not deal with it here, because it is very well explained in How to fix a broken repository? from the Git FAQ.
And if nothing work and this information is lost, you can keep going by removing the broken refs.