TestRepository: Add methods to amend commits or refs
Change-Id: I47082416f6e281262b160ba15272258f9109abd1
This commit is contained in:
parent
d79cadb3cf
commit
da85ca73ff
|
@ -435,6 +435,72 @@ public RevCommit update(String ref, CommitBuilder to) throws Exception {
|
|||
return update(ref, to.create());
|
||||
}
|
||||
|
||||
/**
|
||||
* Amend an existing ref.
|
||||
*
|
||||
* @param ref
|
||||
* the name of the reference to amend, which must already exist.
|
||||
* If {@code ref} does not start with {@code refs/} and is not the
|
||||
* magic names {@code HEAD} {@code FETCH_HEAD} or {@code
|
||||
* MERGE_HEAD}, then {@code refs/heads/} will be prefixed in front
|
||||
* of the given name, thereby assuming it is a branch.
|
||||
* @return commit builder that amends the branch on commit.
|
||||
* @throws Exception
|
||||
*/
|
||||
public CommitBuilder amendRef(String ref) throws Exception {
|
||||
String name = normalizeRef(ref);
|
||||
Ref r = db.getRef(name);
|
||||
if (r == null)
|
||||
throw new IOException("Not a ref: " + ref);
|
||||
return amend(pool.parseCommit(r.getObjectId()), branch(name).commit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Amend an existing commit.
|
||||
*
|
||||
* @param id
|
||||
* the id of the commit to amend.
|
||||
* @return commit builder.
|
||||
* @throws Exception
|
||||
*/
|
||||
public CommitBuilder amend(AnyObjectId id) throws Exception {
|
||||
return amend(pool.parseCommit(id), commit());
|
||||
}
|
||||
|
||||
private CommitBuilder amend(RevCommit old, CommitBuilder b) throws Exception {
|
||||
pool.parseBody(old);
|
||||
b.author(old.getAuthorIdent());
|
||||
b.committer(old.getCommitterIdent());
|
||||
b.message(old.getFullMessage());
|
||||
// Use the committer name from the old commit, but update it after ticking
|
||||
// the clock in CommitBuilder#create().
|
||||
b.updateCommitterTime = true;
|
||||
|
||||
// Reset parents to original parents.
|
||||
b.noParents();
|
||||
for (int i = 0; i < old.getParentCount(); i++)
|
||||
b.parent(old.getParent(i));
|
||||
|
||||
// Reset tree to original tree; resetting parents reset tree contents to the
|
||||
// first parent.
|
||||
b.tree.clear();
|
||||
try (TreeWalk tw = new TreeWalk(db)) {
|
||||
tw.reset(old.getTree());
|
||||
tw.setRecursive(true);
|
||||
while (tw.next()) {
|
||||
b.edit(new PathEdit(tw.getPathString()) {
|
||||
@Override
|
||||
public void apply(DirCacheEntry ent) {
|
||||
ent.setFileMode(tw.getFileMode(0));
|
||||
ent.setObjectId(tw.getObjectId(0));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a reference to point to an object.
|
||||
*
|
||||
|
@ -452,17 +518,7 @@ public RevCommit update(String ref, CommitBuilder to) throws Exception {
|
|||
* @throws Exception
|
||||
*/
|
||||
public <T extends AnyObjectId> T update(String ref, T obj) throws Exception {
|
||||
if (Constants.HEAD.equals(ref)) {
|
||||
// nothing
|
||||
} else if ("FETCH_HEAD".equals(ref)) {
|
||||
// nothing
|
||||
} else if ("MERGE_HEAD".equals(ref)) {
|
||||
// nothing
|
||||
} else if (ref.startsWith(Constants.R_REFS)) {
|
||||
// nothing
|
||||
} else
|
||||
ref = Constants.R_HEADS + ref;
|
||||
|
||||
ref = normalizeRef(ref);
|
||||
RefUpdate u = db.updateRef(ref);
|
||||
u.setNewObjectId(obj);
|
||||
switch (u.forceUpdate()) {
|
||||
|
@ -478,6 +534,20 @@ public <T extends AnyObjectId> T update(String ref, T obj) throws Exception {
|
|||
}
|
||||
}
|
||||
|
||||
private static String normalizeRef(String ref) {
|
||||
if (Constants.HEAD.equals(ref)) {
|
||||
// nothing
|
||||
} else if ("FETCH_HEAD".equals(ref)) {
|
||||
// nothing
|
||||
} else if ("MERGE_HEAD".equals(ref)) {
|
||||
// nothing
|
||||
} else if (ref.startsWith(Constants.R_REFS)) {
|
||||
// nothing
|
||||
} else
|
||||
ref = Constants.R_HEADS + ref;
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Soft-reset HEAD to a detached state.
|
||||
* <p>
|
||||
|
@ -807,6 +877,8 @@ public class CommitBuilder {
|
|||
|
||||
private boolean insertChangeId;
|
||||
|
||||
private boolean updateCommitterTime;
|
||||
|
||||
CommitBuilder() {
|
||||
branch = null;
|
||||
}
|
||||
|
@ -930,8 +1002,11 @@ public RevCommit create() throws Exception {
|
|||
setAuthorAndCommitter(c);
|
||||
if (author != null)
|
||||
c.setAuthor(author);
|
||||
if (committer != null)
|
||||
if (committer != null) {
|
||||
if (updateCommitterTime)
|
||||
committer = new PersonIdent(committer, new Date(now));
|
||||
c.setCommitter(committer);
|
||||
}
|
||||
|
||||
ObjectId commitId;
|
||||
try (ObjectInserter ins = inserter) {
|
||||
|
|
|
@ -43,19 +43,29 @@
|
|||
|
||||
package org.eclipse.jgit.junit;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
|
||||
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.AnyObjectId;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectLoader;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.revwalk.RevBlob;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevObject;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -76,7 +86,7 @@ public void setUp() throws Exception {
|
|||
@After
|
||||
public void tearDown() {
|
||||
rw.close();
|
||||
tr.getRepository().close();
|
||||
repo.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -168,4 +178,98 @@ public void resetFromDetachedHead() throws Exception {
|
|||
assertEquals(detached, head.getObjectId());
|
||||
assertFalse(head.isSymbolic());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void amendRef() throws Exception {
|
||||
RevCommit root = tr.commit()
|
||||
.add("todelete", "to be deleted")
|
||||
.create();
|
||||
RevCommit orig = tr.commit().parent(root)
|
||||
.rm("todelete")
|
||||
.add("foo", "foo contents")
|
||||
.add("bar", "bar contents")
|
||||
.add("dir/baz", "baz contents")
|
||||
.create();
|
||||
rw.parseBody(orig);
|
||||
tr.branch("master").update(orig);
|
||||
assertEquals("foo contents", blobAsString(orig, "foo"));
|
||||
assertEquals("bar contents", blobAsString(orig, "bar"));
|
||||
assertEquals("baz contents", blobAsString(orig, "dir/baz"));
|
||||
|
||||
RevCommit amended = tr.amendRef("master")
|
||||
.tick(3)
|
||||
.add("bar", "fixed bar contents")
|
||||
.create();
|
||||
assertEquals(amended, repo.getRef("refs/heads/master").getObjectId());
|
||||
rw.parseBody(amended);
|
||||
|
||||
assertEquals(1, amended.getParentCount());
|
||||
assertEquals(root, amended.getParent(0));
|
||||
assertEquals(orig.getFullMessage(), amended.getFullMessage());
|
||||
assertEquals(orig.getAuthorIdent(), amended.getAuthorIdent());
|
||||
|
||||
// Committer name/email is the same, but time was incremented.
|
||||
assertEquals(new PersonIdent(orig.getCommitterIdent(), new Date(0)),
|
||||
new PersonIdent(amended.getCommitterIdent(), new Date(0)));
|
||||
assertTrue(orig.getCommitTime() < amended.getCommitTime());
|
||||
|
||||
assertEquals("foo contents", blobAsString(amended, "foo"));
|
||||
assertEquals("fixed bar contents", blobAsString(amended, "bar"));
|
||||
assertEquals("baz contents", blobAsString(amended, "dir/baz"));
|
||||
assertNull(TreeWalk.forPath(repo, "todelete", amended.getTree()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void amendHead() throws Exception {
|
||||
repo.updateRef("HEAD").link("refs/heads/master");
|
||||
RevCommit root = tr.commit()
|
||||
.add("foo", "foo contents")
|
||||
.create();
|
||||
RevCommit orig = tr.commit().parent(root)
|
||||
.message("original message")
|
||||
.add("bar", "bar contents")
|
||||
.create();
|
||||
tr.branch("master").update(orig);
|
||||
|
||||
RevCommit amended = tr.amendRef("HEAD")
|
||||
.add("foo", "fixed foo contents")
|
||||
.create();
|
||||
|
||||
Ref head = repo.getRef(Constants.HEAD);
|
||||
assertEquals(amended, head.getObjectId());
|
||||
assertTrue(head.isSymbolic());
|
||||
assertEquals("refs/heads/master", head.getTarget().getName());
|
||||
|
||||
rw.parseBody(amended);
|
||||
assertEquals("original message", amended.getFullMessage());
|
||||
assertEquals("fixed foo contents", blobAsString(amended, "foo"));
|
||||
assertEquals("bar contents", blobAsString(amended, "bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void amendCommit() throws Exception {
|
||||
RevCommit root = tr.commit()
|
||||
.add("foo", "foo contents")
|
||||
.create();
|
||||
RevCommit orig = tr.commit().parent(root)
|
||||
.message("original message")
|
||||
.add("bar", "bar contents")
|
||||
.create();
|
||||
RevCommit amended = tr.amend(orig.copy())
|
||||
.add("foo", "fixed foo contents")
|
||||
.create();
|
||||
|
||||
rw.parseBody(amended);
|
||||
assertEquals("original message", amended.getFullMessage());
|
||||
assertEquals("fixed foo contents", blobAsString(amended, "foo"));
|
||||
assertEquals("bar contents", blobAsString(amended, "bar"));
|
||||
}
|
||||
|
||||
private String blobAsString(AnyObjectId treeish, String path)
|
||||
throws Exception {
|
||||
RevObject obj = tr.get(rw.parseTree(treeish), path);
|
||||
assertSame(RevBlob.class, obj.getClass());
|
||||
ObjectLoader loader = rw.getObjectReader().open(obj);
|
||||
return new String(loader.getCachedBytes(), UTF_8);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue