Remove spurious commit parent pointer
This will correct the parents without changing anything else (eg. committer dates):
git filter-branch --tag-name-filter cat --parent-filter 'test $GIT_COMMIT = [sha of 1.02-6] && echo "-p [sha of 1.02-3]" || cat' -- 1.02-1..master
You will have to replace the bracketed text with the appropriate commit IDs. If you have more downstream branches that need to be rewritten, change 1.02-1..master
to --all
and be prepared to wait.
Of course, don't use this or any other solution if others have branched from any commits after the ones you want to edit. They will hate you.
The easiest way to do this (in git >= 1.6.5) is to use:
git replace --edit <sha>
and remove/add/change the Parent: lines.
Once you are happy the change is right, you can rewrite the commits to make the change permanent:
git filter-branch --tag-name-filter cat -- --all
In some cases it'll be noticeably quicker to only rewrite the commits involved and not the full history (thanks to Michael for mentioning this in the comments); e.g. to rewrite only commits on the current branch:
git filter-branch --tag-name-filter cat -- <new parent sha>..head
If you're not sure, use --all
, otherwise you risk ending up with other branches/tags still referencing the temporary replacement object.
You can do it manually using the git commit-tree
internal command.
We want to edit the commit tagged 1.02-6
to remove the spurious parent pointer (to 56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4
).
First, read the information from the existing commit object:
user@host:/path/repo.git$ git cat-file -p 1.02-6
tree c658aa1ebcf2bf2a607696c7868b875be72fb01f
parent 56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4
parent 4e671bf1d2298729c9e5cfd8229051cfe2c40831
author James Damour (Suvarov454) <[email protected]> 1146319620 -0400
committer Bazaar Package Importer <[email protected]> 1146319620 -0400
The "main/" in the Section line of debian/control should be assumed.
Extract the commit message using git log --format=%B -n 1 1.02-6
.
Now create a new commit with the same content (excluding the spurious parent link, and the committer info):
git log --format=%B -n 1 1.02-6 | \
GIT_AUTHOR_NAME="James Damour (Suvarov454)" \
GIT_AUTHOR_EMAIL="[email protected]" \
GIT_AUTHOR_DATE="1146319620 -0400" \
git commit-tree c658aa1ebcf2bf2a607696c7868b875be72fb01f \
-p 4e671bf1d2298729c9e5cfd8229051cfe2c40831
This created a new commit, and printed its hash (cc32e66
...). Now turn it into a new branch:
git checkout -b fixed_commit cc32e66
and rebase master
onto the new branch:
git checkout master
git rebase fixed_commit
And we're done:
You probably want to delete the old branches and re-tag the appropriate commits.
Actually it might be easier to use git filter-branch --parent-filter
. I haven't tried that.
You could try a rebase. There is an example a bit down (search for --onto) that I think is similar to your case.
I think you need to do
git rebase --onto 1.02-1 1.02-3
which should put everything after 1.02-3 onto 1.02-1 and that is probably what you want.
Remember that the hashes will be different on everything from the first changed commit but I assume you are doing this as a first step in moving from bzr so no-one else should have cloned this yet.