Reputation: 33861
If I run git replace --graft SHA
on a simple test repo, it seems to correctly truncate the repo (with respect to the provided SHA
) when viewed via git log
.
However on a more complicated repo when I try the same thing, it instead seems to 'replace' the original commit with another - and it keeps all the previous commits surprisingly. The only difference seems to be that the commit has a gpg signature:
git replace --graft af3b4b8a5f98db343b7fc05789aa9656e786d080
warning: the original commit 'af3b4b8a5f98db343b7fc05789aa9656e786d080' has a gpg signature
warning: the signature will be removed in the replacement commit!
Why is this happening? And how can I correctly make it truncate the commit log?
Surprisingly it correctly seems to show that the commit has no parent (if I try reference af3b4b8a5f98db343b7fc05789aa9656e786d080~1
) yet git log
still shows commits before it.
git log af3b4b8a5f98db343b7fc05789aa9656e786d080~1
fatal: ambiguous argument 'af3b4b8a5f98db343b7fc05789aa9656e786d080~1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
The repo in question is https://github.com/eugenp/tutorials and the commit I'm grafting is af3b4b8a5f98db343b7fc05789aa9656e786d080
.
So I'm basically doing:
git clone https://github.com/eugenp/tutorials
cd tutorials
git replace --graft af3b4b8a5f98db343b7fc05789aa9656e786d080
git log | tail -n 10 # this shows commits before af3b4b8a5f98db343b7fc05789aa9656e786d080 hence it's not truncating
Upvotes: 0
Views: 169
Reputation: 265131
git log af3b4b8a5f98db343b7fc05789aa9656e786d080
shows only a single commit. Your repository has multiple root commits after replacing with the graft commit; this happens if you do not graft/truncate all sides of a merge.
The following graphs should help explaining this behavior.
Original history:
R--A--B--C---M--N--... (HEAD -> master)
\ /
`--D--E--F
D
has one parent R
, which has 2 children (A
and D
)
After replacing E
with E'
(the grafted commit):
R--A--B--C---M--N--... (HEAD -> master)
/
E'-F
As you can see, the "truncated" history now has two root commits (the new E'
commit and the original R
root commit). The old root commit is still reachable via the parent of the merge commit M
.
Running git log
(which is identical to running git log HEAD
) will show commits R
, A..C
, M
, and E'
(the grafted commit) and F
.
R
is still reachable through one of its children that haven't been replaced with a graft.
Everything is working as expected. If you want to fully truncate your history, you have to replace a non-merged commit or graft both sides of the merge (or all sides of the merge in case of octopus merges).
Upvotes: 1