Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDemetr Starshov2020-08-12 21:47:15 +0000
committerDemetr Starshov2020-08-27 01:39:48 +0000
commitc084729f79c840e74557a5df38b5259247c4ddbd (patch)
tree60992f1f467412f684879deaa5338cc5316e47b6 /org.eclipse.jgit
parent29e998a0e6415fe2f1439be5fe28537c6d3d3dea (diff)
downloadjgit-c084729f79c840e74557a5df38b5259247c4ddbd.tar.gz
jgit-c084729f79c840e74557a5df38b5259247c4ddbd.tar.xz
jgit-c084729f79c840e74557a5df38b5259247c4ddbd.zip
ResolveMerger: choose OURS on gitlink when ignoreConflicts
Option ignoreConflicts is used when a caller want to create a virtual commit and use it in a future merge (recursive merge) or show it on UI (e.g. Gerrit). According to contract in case of ignoreConflicts ResolveMerger should populate only stage 0 for entries with merge conflicts as if there is no conflict. Current implementation breaks this contract for cases when gitlink revision is ambiguous. Therefore, always select 'ours' when we merge in ignoreConflicts mode. This will satisfy the contract contract, so recursive merge can succeed, however it is an arbitrary decision, so it is not guaranteed to select best GITLINK in all cases. GITLINK merging is a special case of recursive merge because of limitations of GITLINK type of entry. It can't contain more than 1 sha-1 so jgit can't write merge conflicts in place like it can with a blob. Ideally we could signal the conflict with a special value (like '0000...'), but that must be supported by all tooling (git fsck, c-git)." Signed-off-by: Demetr Starshov <dstarshov@google.com> Change-Id: Id4e9bebc8e828f7a1ef9f83259159137df477d89
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java20
1 files changed, 11 insertions, 9 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index 508f7ba62d..a88da6581b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -588,7 +588,8 @@ public class ResolveMerger extends ThreeWayMerger {
final int modeO = tw.getRawMode(T_OURS);
final int modeT = tw.getRawMode(T_THEIRS);
final int modeB = tw.getRawMode(T_BASE);
-
+ boolean gitLinkMerging = isGitLink(modeO) || isGitLink(modeT)
+ || isGitLink(modeB);
if (modeO == 0 && modeT == 0 && modeB == 0)
// File is either untracked or new, staged but uncommitted
return true;
@@ -737,20 +738,20 @@ public class ResolveMerger extends ThreeWayMerger {
return false;
}
- boolean gitlinkConflict = isGitLink(modeO) || isGitLink(modeT);
- // Don't attempt to resolve submodule link conflicts
- if (gitlinkConflict) {
+ if (gitLinkMerging && ignoreConflicts) {
+ // Always select 'ours' in case of GITLINK merge failures so
+ // a caller can use virtual commit.
+ add(tw.getRawPath(), ours, DirCacheEntry.STAGE_0, EPOCH, 0);
+ return true;
+ } else if (gitLinkMerging) {
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0);
-
MergeResult<SubmoduleConflict> result = createGitLinksMergeResult(
base, ours, theirs);
result.setContainsConflicts(true);
mergeResults.put(tw.getPathString(), result);
- if (!ignoreConflicts) {
- unmergedPaths.add(tw.getPathString());
- }
+ unmergedPaths.add(tw.getPathString());
return true;
} else if (!attributes.canBeContentMerged()) {
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
@@ -806,7 +807,8 @@ public class ResolveMerger extends ThreeWayMerger {
}
if (nonTree(modeT)) {
if (e != null) {
- addToCheckout(tw.getPathString(), e, attributes);
+ addToCheckout(tw.getPathString(), e,
+ attributes);
}
}
}

Back to the top