How can I determine why git merging deleted some lines of code?

We had a release, and the deal in question (daf7110) was in a story that was combined with the master. At this point (85a13270), the wizard has lines of code that were added by daf7110.

When one of our developers merged the wizards into his own branch (dev-branch), the lines of code disappeared. They never existed in the history of merge developers. I checked this with:

git checkout c513d2 # <--last commit on dev-branch before the merge git log -S string_that_was_added -- lib/File/It/Was/In.pm 

So:

  • The code never existed in the dev branch before merging.
  • It was on the server, added with "git merge-base c513d2 85a13270"

How can I get more details on why git merge logic decided that code should not survive merge? Or is there some other reason why my fixation could not stand this merger?

+8
git
source share
2 answers

I don’t know the reason why this happened, but I can give some debugging tips.

Firstly, I would make sure you have no odd settings. Make a new repo clone that has both of these branches in an account that does not have a Git configuration. Try a merge. Is this still happening? If not, check your settings, see if there is anything strange; in particular, I would be suspicious of any reerere settings. Also, try merging with --no-rerere-autoupdate to see if it spoils all the lines.

After that, I will start by turning on the maximum granularity for your merge and try merging again:

 GIT_MERGE_VERBOSITY=5 git merge -v master 

This will give you additional information about the decisions that were made by the merger process.

If this doesn't lead to anything useful, you can also try to find out if this happens with different merge strategies or with different default recursive merge strategies. Try git merge -s resolve to try a simpler merge strategy. Still have a problem? How about trying another option for a recursive strategy like git merge -s recursive -X patience ? Do the latter with the additional granularity enabled and see if it makes different decisions than the default merge strategy.

If this does not work, try manually reducing this to the minimum test case. Firstly, I will try to limit myself only to the file in question. Make sure you are running a backup repo, and use git filter-branch to delete all files except the ones in question that there are no lines. When you do this and try merging again, will you get the same results? If not, it is possible that the lines disappear due to the fact that Git gets confused and thinks that they moved to another file when they did not.

If you can still reproduce the problem with only one file, it's time to start the change history of each branch, merging until the problem goes away. For example, starting from the Devek branch, jump about halfway, try merging again and see if the lines have disappeared from the wizard. If they do, try jumping again. If not, go ahead on the develop branch and try again. After you find the commit that introduces the problem on the development side, try to do the same on the main server by moving the commit you merge until the problem goes away.

Now that you are back, as far as possible, try to recreate a simplified version of the story up to this point. Create a new Git repo, check the merge base of these two commits. Then check out the two commits that you tracked back in the separate branches. Can you combine them without problems or does it depend on some aspect of the merge topology between them? If so, try re-creating the complete merge topology; only create the commits needed to complete all the merges in the story. Could this reproduce your problem?

At this point, you should have the simplest possible history to reproduce the problem, with only one file showing it (or find out something interesting when you cannot reduce it and reproduce the problem), I would recommend publishing this repo publicly so that we they could look at it if there is nothing sensitive in this file, or if there is, trying to reduce it further by editing each commit to remove everything except the corresponding lines. You should also be able to replace each relevant line with a placeholder value, leaving you with a minimal test case that does not contain any of your actual code.

All of the above is significant work, but I hope you find something interesting before you complete all of this, or you can skip ahead and create a minimal test case without going through all the intermediate steps. If you have a more minimal test case or the result of one of the above steps, post them and we will be able to consider it more closely.

+11
source share

I met a similar problem, it seems that this was due to the fact that the line of code in question was first introduced by a commit, and then deleted by return, this branch was merged with the master. This line was then re-entered into the dev branch, but was systematically deleted when the dev branch was merged with the master. I assume that somehow git tracks the return and assumes that this line is not needed and should be removed.

+2
source share

All Articles