Home > front end >  git auto merging sometimes doesn't add code
git auto merging sometimes doesn't add code

Time:08-12

I am working in branch A and have the following code in some file

some.property=abc

new.property=def
#some.commented.props=

and in the master branch, the same file contains the following code

some.property=abc

#some.commented.props=

Now after git pull origin master this file is auto merged and here is the final code

some.property=abc

#some.commented.props=

My question is why the codes from branch A are not added to the file? Seems like it kept the code as it is in the master branch.

I added other codes as well but they are properly added, or show conflict where necessary.

CodePudding user response:

What's happened here is virtually certain to be what Jay suspects in a comment. Remember that Git's git merge command is about combining work. It does not mean "override all their files from my files". Instead, it means:

  • figure out what they changed;
  • figure out what I changed;
  • combine the two sets of changes and apply those changes to our common starting point.

It looks like what you changed was some other files, leaving:

some.property=abc

new.property=def
#some.commented.props=

in some file alone.

What they changed is various files, plus changing that one file to read:

some.property=abc

#some.commented.props=

That is, they deleted the new.property=def line.

So Git combines your changes—"do nothing here"—with theirs, "delete this bad line", and the result is that you now have the bad line deleted too.

If the line wasn't actually bad—for instance, perhaps new.property=def was intentional, but just not used yet until you started using it—then what's going on here is that his change is the bad thing and your lack-of-change is the good thing, and you must adjust the merge result because Git is not able to assess the value of any particular change. Git merely combines your changes (none) with his (delete the line), even if his change is a bad thing.

You have three ways to fix the problem:

  1. You can make a new commit on his branch that puts the line back, so that he has not deleted the line. Now he has no "delete the line" change, so that Git won't merge your changes and "his" (now his your) changes by deleting the line, since the line is no longer deleted.

  2. You can use git merge --no-commit to have Git compute the merge result and set it all up, but not actually commit it. Then you can fix the one file before committing, and commit this result. People refer to this as an evil merge, though in this case there's no actual "evil" involved. Be careful with this kind of merge because someone trying to repeat your work later won't necessarily know that you did this, and may get it wrong. Or:

  3. You can go ahead and let git merge delete the line, then make a separate commit just after the merge that puts the line back. Use a commit message that explains what happened and why this is necessary. A sample commit message would be:

    restore new.property=def
    
    In the preceding merge commit, the property definition for
    "new.property" got deleted because the team working on branch
    xyzzy noticed that this property was not used and thought that
    it should be deleted.  However, this property was added back
    in commit <insert hash ID> with the intention
    of using it in the future.  That future has arrived, so the
    setting needs to be restored: the deletion was an error.  (When
    bisecting, skip the merge commit as it's known to be bad and
    to be corrected by this fixup.)
    

There's no really strong reason to prefer any one of these three, but in general my own preference is to fix their branch first if the resulting commit does not break anything. Make the commit message similar to the above, or consider folding that commit in as a fixup so that they never end up deleting the line at all.

To avoid similar future errors, either defer adding new properties until they're actually about to be used, or be sure to update documentation (perhaps comments in the configuration files that hold the properties) to mark these as "for future use, do not delete" or similar.

  • Related