]> source.dussan.org Git - jgit.git/commitdiff
Make pull --rebase on an unborn branch do a checkout 67/137967/2
authorThomas Wolf <thomas.wolf@paranor.ch>
Sun, 3 Mar 2019 23:07:40 +0000 (00:07 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Mon, 10 Jun 2019 14:33:39 +0000 (16:33 +0200)
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>
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java

index 1523b49eccf2e0f70102deed6752a9cd964739b7..74d13883e115bb54176ad0b05984afb3128c98bb 100644 (file)
@@ -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();
        }
index f0ad29db495ed0da963547880e59f903a4965283..bdb2d1bbc5ed6239b9eefc457ff016e92d108f85 100644 (file)
@@ -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)