Browse Source

Make pull --rebase on an unborn branch do a checkout

A merging pull on an unborn branch was already supported. But a
rebasing pull failed. If the user has pull.rebase = true in his
user config, the pull would try to rebase. Rebasing needs a parent
commit, though. Native git handles this case:

  git init
  git remote add origin <URI>
  git pull --rebase origin master

Check up front in PullCommand for the unborn head and just do a
checkout in this case. MergeCommand already has similar code.

Bug: 544965
Change-Id: I1277e1ac0b0364b4623fd791f3d6b07bd5f58fca
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
stable-5.5
Thomas Wolf 6 years ago committed by Matthias Sohn
parent
commit
8a2e221096
  1. 28
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
  2. 45
      org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java

28
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java

@ -718,6 +718,34 @@ public class CloneCommandTest extends RepositoryTestCase {
}
@Test
public void testCloneWithPullMerge() throws Exception {
File directory = createTempDirectory("testCloneRepository1");
try (Git g = Git.init().setDirectory(directory).setBare(false).call()) {
g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME)
.setUri(new URIish(fileUri())).call();
PullResult result = g.pull().setRebase(false).call();
assertTrue(result.isSuccessful());
assertEquals("refs/heads/master",
g.getRepository().getFullBranch());
checkFile(new File(directory, "Test.txt"), "Hello world");
}
}
@Test
public void testCloneWithPullRebase() throws Exception {
File directory = createTempDirectory("testCloneRepository1");
try (Git g = Git.init().setDirectory(directory).setBare(false).call()) {
g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME)
.setUri(new URIish(fileUri())).call();
PullResult result = g.pull().setRebase(true).call();
assertTrue(result.isSuccessful());
assertEquals("refs/heads/master",
g.getRepository().getFullBranch());
checkFile(new File(directory, "Test.txt"), "Hello world");
}
}
private String fileUri() {
return "file://" + git.getRepository().getWorkTree().getAbsolutePath();
}

45
org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java

@ -60,6 +60,7 @@ import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.api.errors.RefNotAdvertisedException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.eclipse.jgit.dircache.DirCacheCheckout;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.BranchConfig.BranchRebaseMode;
@ -67,12 +68,17 @@ import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.TagOpt;
@ -339,6 +345,45 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> {
PullResult result;
if (pullRebaseMode != BranchRebaseMode.NONE) {
try {
Ref head = repo.exactRef(Constants.HEAD);
if (head == null) {
throw new NoHeadException(JGitText
.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
}
ObjectId headId = head.getObjectId();
if (headId == null) {
// Pull on an unborn branch: checkout
try (RevWalk revWalk = new RevWalk(repo)) {
RevCommit srcCommit = revWalk
.parseCommit(commitToMerge);
DirCacheCheckout dco = new DirCacheCheckout(repo,
repo.lockDirCache(), srcCommit.getTree());
dco.setFailOnConflict(true);
dco.setProgressMonitor(monitor);
dco.checkout();
RefUpdate refUpdate = repo
.updateRef(head.getTarget().getName());
refUpdate.setNewObjectId(commitToMerge);
refUpdate.setExpectedOldObjectId(null);
refUpdate.setRefLogMessage("initial pull", false); //$NON-NLS-1$
if (refUpdate.update() != Result.NEW) {
throw new NoHeadException(JGitText
.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
}
monitor.endTask();
return new PullResult(fetchRes, remote,
RebaseResult.result(
RebaseResult.Status.FAST_FORWARD,
srcCommit));
}
}
} catch (NoHeadException e) {
throw e;
} catch (IOException e) {
throw new JGitInternalException(JGitText
.get().exceptionCaughtDuringExecutionOfPullCommand, e);
}
RebaseCommand rebase = new RebaseCommand(repo);
RebaseResult rebaseRes = rebase.setUpstream(commitToMerge)
.setUpstreamName(upstreamName).setProgressMonitor(monitor)

Loading…
Cancel
Save