|
|
@@ -1648,6 +1648,82 @@ public class MergerTest extends RepositoryTestCase { |
|
|
|
indexState(CONTENT)); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Merging two commits when files have equal content, but conflicting file mode |
|
|
|
* in the virtual ancestor. |
|
|
|
* |
|
|
|
* <p> |
|
|
|
* This test has the same set up as |
|
|
|
* {@code checkFileDirMergeConflictInVirtualAncestor_NoConflictInChildren}, only |
|
|
|
* with the mode conflict in A1 and A2. |
|
|
|
*/ |
|
|
|
@Theory |
|
|
|
public void checkModeMergeConflictInVirtualAncestor(MergeStrategy strategy) throws Exception { |
|
|
|
if (!strategy.equals(MergeStrategy.RECURSIVE)) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
Git git = Git.wrap(db); |
|
|
|
|
|
|
|
// master |
|
|
|
writeTrashFile("c", "initial file"); |
|
|
|
git.add().addFilepattern("c").call(); |
|
|
|
RevCommit commitI = git.commit().setMessage("Initial commit").call(); |
|
|
|
|
|
|
|
File a = writeTrashFile("a", "content in Ancestor"); |
|
|
|
git.add().addFilepattern("a").call(); |
|
|
|
RevCommit commitA1 = git.commit().setMessage("Ancestor 1").call(); |
|
|
|
|
|
|
|
a = writeTrashFile("a", "content in Child 1 (commited on master)"); |
|
|
|
git.add().addFilepattern("a").call(); |
|
|
|
// commit C1M |
|
|
|
git.commit().setMessage("Child 1 on master").call(); |
|
|
|
|
|
|
|
git.checkout().setCreateBranch(true).setStartPoint(commitI).setName("branch-to-merge").call(); |
|
|
|
// "a" becomes executable in A2 |
|
|
|
a = writeTrashFile("a", "content in Ancestor"); |
|
|
|
a.setExecutable(true); |
|
|
|
git.add().addFilepattern("a").call(); |
|
|
|
RevCommit commitA2 = git.commit().setMessage("Ancestor 2").call(); |
|
|
|
|
|
|
|
// second branch |
|
|
|
git.checkout().setCreateBranch(true).setStartPoint(commitA1).setName("second-branch").call(); |
|
|
|
a = writeTrashFile("a", "content in Child 2 (commited on second-branch)"); |
|
|
|
git.add().addFilepattern("a").call(); |
|
|
|
// commit C2S |
|
|
|
git.commit().setMessage("Child 2 on second-branch").call(); |
|
|
|
|
|
|
|
// Merge branch-to-merge into second-branch |
|
|
|
MergeResult mergeResult = git.merge().include(commitA2).setStrategy(strategy).call(); |
|
|
|
assertEquals(mergeResult.getNewHead(), null); |
|
|
|
assertEquals(mergeResult.getMergeStatus(), MergeStatus.CONFLICTING); |
|
|
|
// Resolve the conflict manually, merge "a" as non-executable |
|
|
|
a = writeTrashFile("a", "merge conflict resolution"); |
|
|
|
a.setExecutable(false); |
|
|
|
git.add().addFilepattern("a").call(); |
|
|
|
RevCommit commitC3S = git.commit().setMessage("Child 3 on second bug - resolve merge conflict").call(); |
|
|
|
|
|
|
|
// Merge branch-to-merge into master |
|
|
|
git.checkout().setName("master").call(); |
|
|
|
mergeResult = git.merge().include(commitA2).setStrategy(strategy).call(); |
|
|
|
assertEquals(mergeResult.getNewHead(), null); |
|
|
|
assertEquals(mergeResult.getMergeStatus(), MergeStatus.CONFLICTING); |
|
|
|
|
|
|
|
// Resolve the conflict manually - merge "a" as non-executable |
|
|
|
a = writeTrashFile("a", "merge conflict resolution"); |
|
|
|
a.setExecutable(false); |
|
|
|
git.add().addFilepattern("a").call(); |
|
|
|
// commit C4M |
|
|
|
git.commit().setMessage("Child 4 on master - resolve merge conflict").call(); |
|
|
|
|
|
|
|
// Merge C4M (second-branch) into master (C3S) |
|
|
|
// Conflict in virtual base should be here, but there are no conflicts in |
|
|
|
// children |
|
|
|
mergeResult = git.merge().include(commitC3S).call(); |
|
|
|
assertEquals(mergeResult.getMergeStatus(), MergeStatus.MERGED); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private void writeSubmodule(String path, ObjectId commit) |
|
|
|
throws IOException, ConfigInvalidException { |
|
|
|
addSubmoduleToIndex(path, commit); |