Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: Changes keep getting lost due to seemingly random merges

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.

like image 394
akiller Avatar asked May 25 '11 22:05

akiller


People also ask

Why do I keep getting merge conflicts?

Often, merge conflicts happen when people make different changes to the same line of the same file, or when one person edits a file and another person deletes the same file. You must resolve all merge conflicts before you can merge a pull request on GitHub.


1 Answers

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
like image 107
Chris Johnsen Avatar answered Nov 04 '22 09:11

Chris Johnsen