Merge "Add support for using diff3 for rebasing and cherry-pick with conflicts"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 72647cb..4d2fd35 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1730,10 +1730,12 @@
[[change.diff3ConflictView]]change.diff3ConflictView::
+
-Use the diff3 formatter for merge commits with conflicts. With diff3 when
-the conflicts are shown in the "Auto Merge" view, the base section from the
-common parents will be shown as well.
+Use the diff3 formatter for merge, rebase and cherry-picking commits with conflicts.
++
+For merge commits with diff3 when the conflicts are shown in the "Auto Merge" view,
+the base section from the common parents will be shown as well.
This setting takes effect when generating the automerge, which happens on upload.
+Also the setting takes effect when using rebase or cherry-picking in Gerrit Web UI.
Changing the setting leaves existing changes unaffected.
+
Default is `false`.
diff --git a/java/com/google/gerrit/server/change/RebaseChangeOp.java b/java/com/google/gerrit/server/change/RebaseChangeOp.java
index a430034..2b6f6c6 100644
--- a/java/com/google/gerrit/server/change/RebaseChangeOp.java
+++ b/java/com/google/gerrit/server/change/RebaseChangeOp.java
@@ -40,6 +40,7 @@
import com.google.gerrit.server.IdentifiedUser.GenericFactory;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.change.RebaseUtil.Base;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
import com.google.gerrit.server.git.GroupCollector;
@@ -67,6 +68,7 @@
import org.eclipse.jgit.diff.Sequence;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.merge.MergeResult;
@@ -121,6 +123,7 @@
private ImmutableListMultimap<String, String> validationOptions = ImmutableListMultimap.of();
private String mergeStrategy;
private boolean verifyNeedsRebase = true;
+ private final boolean useDiff3;
private CodeReviewCommit rebasedCommit;
private PatchSet.Id rebasedPatchSetId;
@@ -136,6 +139,7 @@
ChangeNotes.Factory notesFactory,
GenericFactory identifiedUserFactory,
ProjectCache projectCache,
+ @GerritServerConfig Config cfg,
@Assisted ChangeNotes notes,
@Assisted PatchSet originalPatchSet,
@Assisted ObjectId baseCommitId) {
@@ -147,6 +151,7 @@
notesFactory,
identifiedUserFactory,
projectCache,
+ cfg,
notes,
originalPatchSet);
this.baseCommitId = baseCommitId;
@@ -162,6 +167,7 @@
ChangeNotes.Factory notesFactory,
GenericFactory identifiedUserFactory,
ProjectCache projectCache,
+ @GerritServerConfig Config cfg,
@Assisted ChangeNotes notes,
@Assisted PatchSet originalPatchSet,
@Assisted Change.Id baseChangeId) {
@@ -173,6 +179,7 @@
notesFactory,
identifiedUserFactory,
projectCache,
+ cfg,
notes,
originalPatchSet);
this.baseChangeId = baseChangeId;
@@ -187,6 +194,7 @@
ChangeNotes.Factory notesFactory,
GenericFactory identifiedUserFactory,
ProjectCache projectCache,
+ @GerritServerConfig Config cfg,
ChangeNotes notes,
PatchSet originalPatchSet) {
this.patchSetInserterFactory = patchSetInserterFactory;
@@ -199,6 +207,7 @@
this.notes = notes;
this.projectName = notes.getProjectName();
this.originalPatchSet = originalPatchSet;
+ this.useDiff3 = cfg.getBoolean("change", null, "diff3ConflictView", false);
}
@CanIgnoreReturnValue
@@ -555,7 +564,8 @@
original,
"BASE",
ctx.getRevWalk().parseCommit(base),
- mergeResults);
+ mergeResults,
+ useDiff3);
logger.atFine().log(
"tree of rebased commit: %s (with conflicts, inserter: %s)",
tree.name(), ctx.getInserter());
diff --git a/java/com/google/gerrit/server/git/MergeUtil.java b/java/com/google/gerrit/server/git/MergeUtil.java
index 1adbb67..86893c1 100644
--- a/java/com/google/gerrit/server/git/MergeUtil.java
+++ b/java/com/google/gerrit/server/git/MergeUtil.java
@@ -225,6 +225,34 @@
boolean allowConflicts)
throws IOException, MergeIdenticalTreeException, MergeConflictException,
MethodNotAllowedException, InvalidMergeStrategyException {
+ return createCherryPickFromCommit(
+ inserter,
+ repoConfig,
+ mergeTip,
+ originalCommit,
+ cherryPickCommitterIdent,
+ commitMsg,
+ rw,
+ parentIndex,
+ ignoreIdenticalTree,
+ allowConflicts,
+ false);
+ }
+
+ public CodeReviewCommit createCherryPickFromCommit(
+ ObjectInserter inserter,
+ Config repoConfig,
+ RevCommit mergeTip,
+ RevCommit originalCommit,
+ PersonIdent cherryPickCommitterIdent,
+ String commitMsg,
+ CodeReviewRevWalk rw,
+ int parentIndex,
+ boolean ignoreIdenticalTree,
+ boolean allowConflicts,
+ boolean diff3Format)
+ throws IOException, MergeIdenticalTreeException, MergeConflictException,
+ MethodNotAllowedException, InvalidMergeStrategyException {
ThreeWayMerger m = newThreeWayMerger(inserter, repoConfig);
m.setBase(originalCommit.getParent(parentIndex));
@@ -300,7 +328,15 @@
tree =
mergeWithConflicts(
- rw, inserter, dc, "HEAD", mergeTip, "CHANGE", originalCommit, mergeResults);
+ rw,
+ inserter,
+ dc,
+ "HEAD",
+ mergeTip,
+ "CHANGE",
+ originalCommit,
+ mergeResults,
+ diff3Format);
logger.atFine().log(
"AutoMerge treeId=%s (with conflicts, inserter: %s)", tree.name(), inserter);
}
diff --git a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
index 63edb7b..d828e87 100644
--- a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
@@ -45,6 +45,7 @@
import com.google.gerrit.server.change.ResetCherryPickOp;
import com.google.gerrit.server.change.SetCherryPickOp;
import com.google.gerrit.server.change.ValidationOptionsUtil;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
import com.google.gerrit.server.git.CommitUtil;
@@ -78,6 +79,7 @@
import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
@@ -116,11 +118,13 @@
private final ApprovalsUtil approvalsUtil;
private final NotifyResolver notifyResolver;
private final BatchUpdate.Factory batchUpdateFactory;
+ private final boolean useDiff3;
@Inject
CherryPickChange(
Sequences seq,
Provider<InternalChangeQuery> queryProvider,
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent myIdent,
GitRepositoryManager gitManager,
Provider<IdentifiedUser> user,
@@ -147,6 +151,7 @@
this.approvalsUtil = approvalsUtil;
this.notifyResolver = notifyResolver;
this.batchUpdateFactory = batchUpdateFactory;
+ this.useDiff3 = cfg.getBoolean("change", null, "diff3ConflictView", false);
}
/**
@@ -376,7 +381,8 @@
revWalk,
input.parent - 1,
input.allowEmpty,
- input.allowConflicts);
+ input.allowConflicts,
+ useDiff3);
logger.atFine().log("flushing inserter %s", oi);
oi.flush();
} catch (MergeIdenticalTreeException | MergeConflictException e) {
diff --git a/java/com/google/gerrit/server/submit/CherryPick.java b/java/com/google/gerrit/server/submit/CherryPick.java
index 7fe5e69..a213f28 100644
--- a/java/com/google/gerrit/server/submit/CherryPick.java
+++ b/java/com/google/gerrit/server/submit/CherryPick.java
@@ -84,9 +84,11 @@
private PatchSet.Id psId;
private CodeReviewCommit newCommit;
private PatchSetInfo patchSetInfo;
+ private final boolean useDiff3;
private CherryPickOneOp(CodeReviewCommit toMerge) {
super(CherryPick.this.args, toMerge);
+ this.useDiff3 = args.cfg.getBoolean("change", null, "diff3ConflictView", false);
}
@Override
@@ -119,7 +121,8 @@
args.rw,
0,
false,
- false);
+ false,
+ useDiff3);
} catch (MergeConflictException mce) {
// Keep going in the case of a single merge failure; the goal is to
// cherry-pick as many commits as possible.
diff --git a/java/com/google/gerrit/server/submit/SubmitStrategy.java b/java/com/google/gerrit/server/submit/SubmitStrategy.java
index d4dd67a..5346acc 100644
--- a/java/com/google/gerrit/server/submit/SubmitStrategy.java
+++ b/java/com/google/gerrit/server/submit/SubmitStrategy.java
@@ -38,6 +38,7 @@
import com.google.gerrit.server.change.RebaseChangeOp;
import com.google.gerrit.server.change.SetPrivateOp;
import com.google.gerrit.server.change.TestSubmitInput;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.extensions.events.ChangeMerged;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
@@ -66,6 +67,7 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
@@ -115,6 +117,7 @@
final EmailMerge.Factory mergedSenderFactory;
final GitRepositoryManager repoManager;
final LabelNormalizer labelNormalizer;
+ final Config cfg;
final PatchSetInfoFactory patchSetInfoFactory;
final PatchSetUtil psUtil;
final ProjectCache projectCache;
@@ -158,6 +161,7 @@
MergeUtilFactory mergeUtilFactory,
PatchSetInfoFactory patchSetInfoFactory,
PatchSetUtil psUtil,
+ @GerritServerConfig Config cfg,
@GerritPersonIdent PersonIdent serverIdent,
ProjectCache projectCache,
RebaseChangeOp.Factory rebaseFactory,
@@ -189,6 +193,7 @@
this.cmUtil = cmUtil;
this.labelNormalizer = labelNormalizer;
this.projectConfigFactory = projectConfigFactory;
+ this.cfg = cfg;
this.patchSetInfoFactory = patchSetInfoFactory;
this.psUtil = psUtil;
this.projectCache = projectCache;