Our git repo was imported from a different VCS (Perforce) but the standard import was unable to recover branch relations (i.e. that branch 1.1 was derived from branch 1.0). To fix this we added grafts: git replace --graft <commit> <parent>
to record the missing relation from the creation of each branch to its parent commit.
So we have a git repository that has some replacements in .git/refs/replace. (These should probably have been removed by rebasing somehow but perhaps it is too late for that now)
These replacements must be pulled manually using:
git pull origin 'refs/replace/*:refs/replace/*'
A colleague was unaware of this but was somehow able to push a change to the repo such that:
git pull origin 'refs/replace/*:refs/replace/*'
results in a merge conflicts like:
Simple merge did not work, trying automatic merge.
ERROR: /some/file: Not handling case c6aa12b3f446c57921a68c5fc73dae9e086c2bdb -> -> bb909246180daf894ccdb59cc4a4ff398ac62bad
fatal: merge program failed
Automated merge did not work.
Should not be doing an octopus.
Merge with strategy octopus failed
I don't understand what is being merged here. If I use:
git pull origin 'refs/replace/*:refs/replace/*' -s ours
The merge succeeds and I end up (aftering commiting) with a merge message like:
commit 67d7f7cc40826e8a84beed3af9999d39e411e65d
Merge: 718dbe3 c9333d1 b870b22 d3f10f7 77d0835 de79e03 d7f0e7c 97ca1f8 Author: xxxxx
Date: Tue Jul 11 11:33:55 2017 +0100
Merge commits 'refs/replace/00029d7b3e531215f6ce5afb32862b49d652e896', 'refs/replace/03d715c9890e5cec95ac62d1c9ecc54cb78b9f62', '
git claims several files are changed, though these are not files changed recently. I suspect they are the difference between two old branches.
After the merge/pull we have replacements in .git/refs/replace.
My colleague's report claims the changes pushed include grafts replicating 2 of the missing branch relations which he needed. These do not appear in .git/refs/replace at all.
If they are somehow mixed in with the ones pushed earlier there are some other questions:
How was he able to push without resolving the merge conflict first?
Also if you clone from the repository without pulling the replacements the relations he added are still pulled. There are two tell-tale commits with the commit messages like
Former-commit-id: bc735afc1d8bb842733cb94767afb8b42599eb6a
but there is no .git/refs/replace directory describing the replacement.
How could my colleague have been able to push his grafts as permanent changes to the repo that are pulled automatically when the earlier are not? and such that there is no .git/refs/replace directory at all?
Can someone enlighten me as to what might be happening here?
Also is there something I can do to make the other branch relations permanent without rewriting history? My colleague appears to have done this but I can't understand how.
Resolved
To summarise the answers:
In git the opposite of a push is a fetch not a pull
My colleagues push wouldn't have had a merge issue as there wasn't one. Its was artifact of my using 'pull' instead of 'fetch'.
Thanks for the help.