Git: Changes keep getting lost due to seemingly ra

2019-03-11 06:05发布

I have a feeling this will be an obvious answer, but I can't seem to work it out.

What appears to happen is that I commit/push some changes to the server and everything appears fine on my copy.

Another developer then pulls from the server from the same branch (allegedly seeing my changes, as far as I'm aware), makes some modifications, commits them to their own local copy then finally pushes it back to the server.

Somewhere in the middle of doing this my changes get lost as their push (326c8fd0...) causes a merge with lots of delete/add lines resetting the repository back to a much older revision. This has happened a few times now even with fresh copies of the repository.

The highlighted line below (8def6e9..) was a commit I made, the following commits should have been on this same branch assuming the other developer pulled the changes. A merge happens at 326c8fd0 which ends up resetting the repository incorrectly, losing previous changes.

TortoiseGit log

Am I missing something very obvious as to why this is happening? We're both using TortoiseGit.

Sorry for the probably vague explanation.

2条回答
太酷不给撩
2楼-- · 2019-03-11 06:53

If you are losing commits, ensure that neither of you is using --force or a force flag on your gui to get rid of rejected. Take a look at the explanation of the DAG.

http://progit.org/book

hope this helps.

查看更多
Luminary・发光体
3楼-- · 2019-03-11 06:55

In your example, someone is merging f36908d (the first parent; their HEAD at the time of the merge) and 8def6e9 (the second parent; probably the tip of the origin branch at the time of the merge) to produce 326c8fd0.

If the merge commit (326c8fd0) is missing significant pieces of content with respect to either of its parents (f36908d and 8def6e9; you say it is missing pieces of the latter), then whoever create the merge commit is probably executing the merge in an inappropriate fashion.

This person may be using the ours merge strategy (merge or pull with -s ours/--strategy=ours), the ours option to the default recursive merge strategy (merge or pull with -X ours/--strategy-option=ours), or they may just be making bad decisions when manually resolving the merge conflicts.

The ours strategy completely ignores any content changes made in the history all parents but the first. You can usually identify this type of merge because the merge commit and its first parent (i.e. their changes) will have identical trees (i.e. git diff f36908d 326c8fd0 would show no differences).

The ours merge strategy option will also ignore changes from the history of the second parent (i.e. your changes), but only those that conflict with changes made in the history of the first parent (i.e. their changes). In this case, some changes from the second parent may make it into the result, but others may be dropped entirely.

The other likely alternative is that they are just making bad decisions while resolving conflicts generated during a default merge.

Either way, someone will probably have to talk to the user that did the merge to find out exactly what they did, and why they did it so that a policy can be devised to prevent the problem in the future.


To recover, you might redo the merge yourself and them merge the result into the current tip of the history:

git checkout -b remerge f36908d
git merge 8def6e9
# resolve conflicts and commit
git checkout develop
git merge remerge
# maybe resolve more conflicts

# eventually: git branch -d remerge

Or, if you are okay with rewriting history:

git checkout -b remerge f36908d
git merge 8def6e9
# resolve conflicts and commit
git rebase --onto remerge 326c8fd0 develop
# maybe more conflicts to resolve at each rebased commit
查看更多
登录 后发表回答