summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Pearce <spearce@spearce.org>2014-08-08 11:19:45 -0700
committerShawn Pearce <spearce@spearce.org>2014-08-08 11:31:24 -0700
commit4bd28bc9589abe7bf9ea6bc4dde8b4d683baf61a (patch)
tree3937f9f8a9277d968e1d4ef5b85df3c5b36cf1f1
parent66ad4237be541555a7b6f394924d5dedcfae4714 (diff)
downloadjgit-4bd28bc9589abe7bf9ea6bc4dde8b4d683baf61a.tar.gz
jgit-4bd28bc9589abe7bf9ea6bc4dde8b4d683baf61a.zip
RecursiveMerger: do not insert virtual commits into repository
When merging common ancestors to create a single virtual common ancestor the commit does not need to be inserted into the Git repository. Instead just mock it out in memory as part of the merger's RevWalk pool. Make the author and committer stable and predictable for any given pair of merge bases. It is not necessary for the caller's name or email to be used as the commit will not be written out. Change-Id: I88d5ee4de121950e1b032a5c10486c9d2c42656c
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java35
1 files changed, 21 insertions, 14 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
index af6c1f9647..4889293ad0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
@@ -52,7 +52,9 @@ package org.eclipse.jgit.merge;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
+import java.util.TimeZone;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
@@ -62,7 +64,6 @@ import org.eclipse.jgit.errors.NoMergeBaseException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -90,8 +91,6 @@ public class RecursiveMerger extends ResolveMerger {
*/
public final int MAX_BASES = 200;
- private PersonIdent ident = new PersonIdent(db);
-
/**
* Normal recursive merge when you want a choice of DirCache placement
* inCore
@@ -137,7 +136,9 @@ public class RecursiveMerger extends ResolveMerger {
* the second commit to be merged
* @param callDepth
* the callDepth when this method is called recursively
- * @return the merge base of two commits
+ * @return the merge base of two commits. If a criss-cross merge required a
+ * synthetic merge base this commit is visible only the merger's
+ * RevWalk and will not be in the repository.
* @throws IOException
* @throws IncorrectObjectTypeException
* one of the input objects is not a commit.
@@ -228,22 +229,28 @@ public class RecursiveMerger extends ResolveMerger {
* the tree this commit should capture
* @param parents
* the list of parent commits
- * @return a new (persisted) commit
+ * @return a new commit visible only within this merger's RevWalk.
* @throws IOException
*/
private RevCommit createCommitForTree(ObjectId tree, List<RevCommit> parents)
throws IOException {
CommitBuilder c = new CommitBuilder();
- c.setParentIds(parents);
c.setTreeId(tree);
- c.setAuthor(ident);
- c.setCommitter(ident);
- ObjectInserter odi = db.newObjectInserter();
- ObjectId newCommitId = odi.insert(c);
- odi.flush();
- RevCommit ret = walk.lookupCommit(newCommitId);
- walk.parseHeaders(ret);
- return ret;
+ c.setParentIds(parents);
+ c.setAuthor(mockAuthor(parents));
+ c.setCommitter(c.getAuthor());
+ return RevCommit.parse(walk, c.build());
+ }
+
+ private static PersonIdent mockAuthor(List<RevCommit> parents) {
+ String name = RecursiveMerger.class.getSimpleName();
+ int time = 0;
+ for (RevCommit p : parents)
+ time = Math.max(time, p.getCommitTime());
+ return new PersonIdent(
+ name, name + "@JGit", //$NON-NLS-1$
+ new Date((time + 1) * 1000L),
+ TimeZone.getTimeZone("GMT+0000")); //$NON-NLS-1$
}
/**