0

When using git cherry pick to merge revisions via commits we encounter the following issue of git showing other peoples code as part of the conflict resolution options.

Let's say we have the following history in the develop branch

A----B----1----2 develop

We want to merge the commit revision 1 from develop to the release branch

A----T release

Revision A for both develop and release branch start

public interface Constants {
    String ConstantA = "CONSTANT_A";
}

Revision B in develop

public interface Constants {
    String ConstantA = "CONSTANT_A";
    String ConstantB = "CONSTANT_B";
}

Revision 1 in develop

public interface Constants {
    String ConstantA = "CONSTANT_A";
    String ConstantB = "CONSTANT_B";
    String Constant1 = "CONSTANT_1";
}

Revision 2 in develop

public interface Constants {
    String ConstantA = "CONSTANT_A";
    String ConstantB = "CONSTANT_B";
    String Constant1 = "CONSTANT_1";
    String Constant2 = "CONSTANT_2";
}

Revision T in release

public interface Constants {
    String ConstantA = "CONSTANT_A";
    String ConstantT = "CONSTANT_T";
}

When I switch to the release branch and cherry pick revision 1 I get conflicts as expected.

However the problem is how the conflict is shown, which is as follows

public interface Constants {
    String ConstantA = "CONSTANT_A";
<<<<<<< release
    String ConstantT = "CONSTANT_T";
=======
    String ConstantB = "CONSTANT_B";
    String Constant1 = "CONSTANT_1";
>>>>>>> 60dc0f9 Revision 1
}

The problem is the following line being present

String ConstantB = "CONSTANT_B";

When I go back to my development branch and diff Revision B and Revision 1 I get ONLY the following

String Constant1 = "CONSTANT_1";

Basically I am guessing this is because that Revision B commit is present before Revision A. In a real environment there can be lots more changes before the cherry pick commit that are not in the release branch (Imagine about 40 more constants added), how do I only get the actual diff of my cherry picked commit shown in the conflict. Note that I tried this with rebase --onto but got the same result.

EDIT

The following is the file after cherry picking with the conflict in the diff3 format. git checkout --conflict=diff3 src/Constants.java

public interface Constants {
    String ConstantA = "CONSTANT_A";
<<<<<<< ours
    String ConstantT = "CONSTANT_T";
||||||| base
    String ConstantB = "CONSTANT_B";
=======
    String ConstantB = "CONSTANT_B";
    String Constant1 = "CONSTANT_1";
>>>>>>> theirs
}
MilindaD
  • 7,533
  • 9
  • 43
  • 63
  • If you do `git checkout --conflict=diff3 filename`, then what is reported as base version? – user4003407 Apr 04 '16 at 11:32
  • can you explain the parameters diff3 and filename that I should use – MilindaD Apr 04 '16 at 13:41
  • `diff3` means that conflicted hunks should include not only ours and theirs version but also base version of hunk. And `filename` should be file where merge conflict arise. – user4003407 Apr 04 '16 at 13:48
  • Ran the command and changed the diff format to ours, base, theirs. Still a bit confused to as to how to check the base version though. Added the updated file with diff3 format in the question. – MilindaD Apr 04 '16 at 14:14
  • It looks like, when `git` want to `rebase` or `cherry-pick` commit `C` to current `HEAD`, then it does three-way merge with `ours=HEAD`, `theirs=C` and `base=C^` (parent of `C`). In your case it would be `ours=T`, `theirs=1` and `base=B`. From that point of view `theirs` side add just one line `CONSTANT_1`, but `ours` side remove `CONSTANT_B` line and add `CONSTANT_A` line. That removal of `CONSTANT_B` line in `ours` side make it to be part of conflicted hunk. So that, it included in `base` and `theirs` version of hunk. – user4003407 Apr 09 '16 at 10:19

0 Answers0