InlineEdit: Add method to rebase change edit
Change-Id: I09bbf692bc7812df5f608fc87455aa673b9f0cf9
This commit is contained in:
@@ -3,4 +3,5 @@ include_defs('//gerrit-acceptance-tests/tests.defs')
|
||||
acceptance_tests(
|
||||
srcs = ['ChangeEditIT.java'],
|
||||
labels = ['edit'],
|
||||
deps = ['//lib/joda:joda-time'],
|
||||
)
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package com.google.gerrit.acceptance.edit;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -46,11 +48,16 @@ import com.google.inject.util.Providers;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeUtils;
|
||||
import org.joda.time.DateTimeUtils.MillisProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@NoHttpd
|
||||
public class ChangeEditIT extends AbstractDaemonTest {
|
||||
@@ -84,6 +91,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
|
||||
|
||||
private ReviewDb db;
|
||||
private Change change;
|
||||
private String changeId;
|
||||
private Change change2;
|
||||
private PatchSet ps;
|
||||
private PatchSet ps2;
|
||||
@@ -92,22 +100,33 @@ public class ChangeEditIT extends AbstractDaemonTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
db = reviewDbProvider.open();
|
||||
String changeId = newChange(git, admin.getIdent());
|
||||
change = getChange(changeId);
|
||||
changeId = newChange(git, admin.getIdent());
|
||||
ps = getCurrentPatchSet(changeId);
|
||||
amendChange(git, admin.getIdent(), changeId);
|
||||
change = getChange(changeId);
|
||||
assertNotNull(ps);
|
||||
changeId = newChange2(git, admin.getIdent());
|
||||
change2 = getChange(changeId);
|
||||
String changeId2 = newChange2(git, admin.getIdent());
|
||||
change2 = getChange(changeId2);
|
||||
assertNotNull(change2);
|
||||
ps2 = getCurrentPatchSet(changeId);
|
||||
ps2 = getCurrentPatchSet(changeId2);
|
||||
assertNotNull(ps2);
|
||||
session = new RestSession(server, admin);
|
||||
atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
|
||||
identifiedUserFactory.create(Providers.of(db), admin.getId())));
|
||||
final long clockStepMs = MILLISECONDS.convert(1, SECONDS);
|
||||
final AtomicLong clockMs = new AtomicLong(
|
||||
new DateTime(2009, 9, 30, 17, 0, 0).getMillis());
|
||||
DateTimeUtils.setCurrentMillisProvider(new MillisProvider() {
|
||||
@Override
|
||||
public long getMillis() {
|
||||
return clockMs.getAndAdd(clockStepMs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
DateTimeUtils.setCurrentMillisSystem();
|
||||
db.close();
|
||||
}
|
||||
|
||||
@@ -128,6 +147,21 @@ public class ChangeEditIT extends AbstractDaemonTest {
|
||||
|
||||
@Test
|
||||
public void publishEdit() throws Exception {
|
||||
assertEquals(RefUpdate.Result.NEW,
|
||||
modifier.createEdit(
|
||||
change,
|
||||
getCurrentPatchSet(changeId)));
|
||||
assertEquals(RefUpdate.Result.FORCED,
|
||||
modifier.modifyFile(
|
||||
editUtil.byChange(change).get(),
|
||||
FILE_NAME,
|
||||
CONTENT_NEW2));
|
||||
editUtil.publish(editUtil.byChange(change).get());
|
||||
assertFalse(editUtil.byChange(change).isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rebaseEdit() throws Exception {
|
||||
assertEquals(RefUpdate.Result.NEW,
|
||||
modifier.createEdit(
|
||||
change,
|
||||
@@ -137,8 +171,23 @@ public class ChangeEditIT extends AbstractDaemonTest {
|
||||
editUtil.byChange(change).get(),
|
||||
FILE_NAME,
|
||||
CONTENT_NEW));
|
||||
editUtil.publish(editUtil.byChange(change).get());
|
||||
assertFalse(editUtil.byChange(change).isPresent());
|
||||
ChangeEdit edit = editUtil.byChange(change).get();
|
||||
PatchSet current = getCurrentPatchSet(changeId);
|
||||
assertEquals(current.getPatchSetId() - 1,
|
||||
edit.getBasePatchSet().getPatchSetId());
|
||||
Date beforeRebase = edit.getEditCommit().getCommitterIdent().getWhen();
|
||||
modifier.rebaseEdit(edit, current);
|
||||
edit = editUtil.byChange(change).get();
|
||||
assertArrayEquals(CONTENT_NEW,
|
||||
toBytes(fileUtil.getContent(edit.getChange().getProject(),
|
||||
edit.getRevision().get(), FILE_NAME)));
|
||||
assertArrayEquals(CONTENT_NEW2,
|
||||
toBytes(fileUtil.getContent(edit.getChange().getProject(),
|
||||
edit.getRevision().get(), FILE_NAME2)));
|
||||
assertEquals(current.getPatchSetId(),
|
||||
edit.getBasePatchSet().getPatchSetId());
|
||||
Date afterRebase = edit.getEditCommit().getCommitterIdent().getWhen();
|
||||
assertFalse(beforeRebase.equals(afterRebase));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -332,6 +381,13 @@ public class ChangeEditIT extends AbstractDaemonTest {
|
||||
return push.to(git, "refs/for/master").getChangeId();
|
||||
}
|
||||
|
||||
private String amendChange(Git git, PersonIdent ident, String changeId) throws Exception {
|
||||
PushOneCommit push =
|
||||
pushFactory.create(db, ident, PushOneCommit.SUBJECT, FILE_NAME2,
|
||||
new String(CONTENT_NEW2), changeId);
|
||||
return push.to(git, "refs/for/master").getChangeId();
|
||||
}
|
||||
|
||||
private String newChange2(Git git, PersonIdent ident) throws Exception {
|
||||
PushOneCommit push =
|
||||
pushFactory.create(db, ident, PushOneCommit.SUBJECT, FILE_NAME,
|
||||
|
||||
@@ -46,6 +46,8 @@ import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.merge.MergeStrategy;
|
||||
import org.eclipse.jgit.merge.ThreeWayMerger;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
@@ -126,6 +128,61 @@ public class ChangeEditModifier {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebase change edit on latest patch set
|
||||
*
|
||||
* @param edit change edit that contains edit to rebase
|
||||
* @param current patch set to rebase the edit on
|
||||
* @throws AuthException
|
||||
* @throws InvalidChangeOperationException
|
||||
* @throws IOException
|
||||
*/
|
||||
public RefUpdate.Result rebaseEdit(ChangeEdit edit, PatchSet current)
|
||||
throws AuthException, InvalidChangeOperationException, IOException {
|
||||
if (!currentUser.get().isIdentifiedUser()) {
|
||||
throw new AuthException("Authentication required");
|
||||
}
|
||||
|
||||
Change change = edit.getChange();
|
||||
IdentifiedUser me = (IdentifiedUser) currentUser.get();
|
||||
String refName = editRefName(me.getAccountId(), change.getId());
|
||||
Repository repo = gitManager.openRepository(change.getProject());
|
||||
try {
|
||||
RevWalk rw = new RevWalk(repo);
|
||||
ObjectInserter inserter = repo.newObjectInserter();
|
||||
try {
|
||||
RevCommit editCommit = edit.getEditCommit();
|
||||
RevCommit mergeTip = rw.parseCommit(ObjectId.fromString(
|
||||
current.getRevision().get()));
|
||||
ThreeWayMerger m = MergeStrategy.RESOLVE.newMerger(repo, true);
|
||||
m.setObjectInserter(inserter);
|
||||
m.setBase(editCommit.getParent(0));
|
||||
if (m.merge(mergeTip, editCommit)) {
|
||||
ObjectId tree = m.getResultTreeId();
|
||||
|
||||
CommitBuilder mergeCommit = new CommitBuilder();
|
||||
mergeCommit.setTreeId(tree);
|
||||
mergeCommit.setParentId(mergeTip);
|
||||
mergeCommit.setAuthor(editCommit.getAuthorIdent());
|
||||
mergeCommit.setCommitter(new PersonIdent(
|
||||
editCommit.getCommitterIdent(), TimeUtil.nowTs()));
|
||||
mergeCommit.setMessage(editCommit.getFullMessage());
|
||||
ObjectId newEdit = inserter.insert(mergeCommit);
|
||||
inserter.flush();
|
||||
return update(repo, me, refName, rw, editCommit, newEdit);
|
||||
} else {
|
||||
// TODO(davido): Allow to resolve conflicts inline
|
||||
throw new InvalidChangeOperationException("merge conflict");
|
||||
}
|
||||
} finally {
|
||||
rw.release();
|
||||
inserter.release();
|
||||
}
|
||||
} finally {
|
||||
repo.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify file in existing change edit from its base commit.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user