diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java index de75fd5b6..48ede966f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java @@ -48,7 +48,9 @@ import java.io.FileOutputStream; import java.io.IOException; +import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode; import org.eclipse.jgit.api.MergeResult.MergeStatus; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RepositoryTestCase; import org.eclipse.jgit.lib.StoredConfig; @@ -125,6 +127,46 @@ public void testPullConflict() throws Exception { assertFileContentsEqual(targetFile, result); } + public void testPullLocalConflict() throws Exception { + target.branchCreate().setName("basedOnMaster").setStartPoint( + "refs/heads/master").setUpstreamMode(SetupUpstreamMode.TRACK) + .call(); + target.getRepository().updateRef(Constants.HEAD).link( + "refs/heads/basedOnMaster"); + PullResult res = target.pull().call(); + // nothing to update since we don't have different data yet + assertNull(res.getFetchResult()); + assertTrue(res.getMergeResult().getMergeStatus().equals( + MergeStatus.ALREADY_UP_TO_DATE)); + + assertFileContentsEqual(targetFile, "Hello world"); + + // change the file in master + target.getRepository().updateRef(Constants.HEAD).link( + "refs/heads/master"); + writeToFile(targetFile, "Master change"); + target.add().addFilepattern("SomeFile.txt").call(); + target.commit().setMessage("Source change in master").call(); + + // change the file in slave + target.getRepository().updateRef(Constants.HEAD).link( + "refs/heads/basedOnMaster"); + writeToFile(targetFile, "Slave change"); + target.add().addFilepattern("SomeFile.txt").call(); + target.commit().setMessage("Source change in based on master").call(); + + res = target.pull().call(); + + String sourceChangeString = "Master change\n>>>>>>> branch 'refs/heads/master' of local repository"; + + assertNull(res.getFetchResult()); + assertEquals(res.getMergeResult().getMergeStatus(), + MergeStatus.CONFLICTING); + String result = "<<<<<<< HEAD\nSlave change\n=======\n" + + sourceChangeString + "\n"; + assertFileContentsEqual(targetFile, result); + } + @Override protected void setUp() throws Exception { super.setUp(); diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties index 409b43492..8af6e315f 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties @@ -113,6 +113,7 @@ corruptionDetectedReReadingAt=Corruption detected re-reading at {0} couldNotCheckOutBecauseOfConflicts=Could not check out because of conflicts couldNotDeleteLockFileShouldNotHappen=Could not delete lock file. Should not happen couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index file. Should not happen +couldNotGetAdvertisedRef=Could not get advertised Ref for branch {0} couldNotLockHEAD=Could not lock HEAD couldNotReadIndexInOneGo=Could not read index in one go, only {0} out of {1} read couldNotRenameDeleteOldIndex=Could not rename delete old index diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java index d6c601800..6a75a9eb8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java @@ -173,6 +173,7 @@ public static JGitText get() { /***/ public String couldNotCheckOutBecauseOfConflicts; /***/ public String couldNotDeleteLockFileShouldNotHappen; /***/ public String couldNotDeleteTemporaryIndexFileShouldNotHappen; + /***/ public String couldNotGetAdvertisedRef; /***/ public String couldNotLockHEAD; /***/ public String couldNotReadIndexInOneGo; /***/ public String couldNotRenameDeleteOldIndex; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java index b7f09d9a7..acbf3f10a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java @@ -157,14 +157,6 @@ public PullResult call() throws WrongRepositoryStateException, throw new InvalidConfigurationException(MessageFormat.format( JGitText.get().missingConfigurationForKey, missingKey)); } - final String remoteUri = repo.getConfig().getString("remote", remote, - ConfigConstants.CONFIG_KEY_URL); - if (remoteUri == null) { - String missingKey = ConfigConstants.CONFIG_REMOTE_SECTION + DOT - + remote + DOT + ConfigConstants.CONFIG_KEY_URL; - throw new InvalidConfigurationException(MessageFormat.format( - JGitText.get().missingConfigurationForKey, missingKey)); - } // get the name of the branch in the remote repository // stored in configuration key branch..merge @@ -175,13 +167,14 @@ public PullResult call() throws WrongRepositoryStateException, // check if the branch is configured for pull-rebase remoteBranchName = repoConfig.getString( ConfigConstants.CONFIG_BRANCH_SECTION, branchName, - ConfigConstants.CONFIG_KEY_MERGE); + ConfigConstants.CONFIG_KEY_REBASE); if (remoteBranchName != null) { // TODO implement pull-rebase throw new JGitInternalException( "Pull with rebase is not yet supported"); } } + if (remoteBranchName == null) { String missingKey = ConfigConstants.CONFIG_BRANCH_SECTION + DOT + branchName + DOT + ConfigConstants.CONFIG_KEY_MERGE; @@ -189,45 +182,66 @@ public PullResult call() throws WrongRepositoryStateException, JGitText.get().missingConfigurationForKey, missingKey)); } - if (monitor.isCancelled()) - throw new CanceledException(MessageFormat.format( - JGitText.get().operationCanceled, - JGitText.get().pullTaskName)); + final boolean isRemote = !remote.equals("."); + String remoteUri; + FetchResult fetchRes; + if (isRemote) { + remoteUri = repo.getConfig().getString("remote", remote, + ConfigConstants.CONFIG_KEY_URL); + if (remoteUri == null) { + String missingKey = ConfigConstants.CONFIG_REMOTE_SECTION + DOT + + remote + DOT + ConfigConstants.CONFIG_KEY_URL; + throw new InvalidConfigurationException(MessageFormat.format( + JGitText.get().missingConfigurationForKey, missingKey)); + } - FetchCommand fetch = new FetchCommand(repo); - fetch.setRemote(remote); - if (monitor != null) - fetch.setProgressMonitor(monitor); - fetch.setTimeout(this.timeout); + if (monitor.isCancelled()) + throw new CanceledException(MessageFormat.format( + JGitText.get().operationCanceled, + JGitText.get().pullTaskName)); - FetchResult fetchRes = fetch.call(); + FetchCommand fetch = new FetchCommand(repo); + fetch.setRemote(remote); + if (monitor != null) + fetch.setProgressMonitor(monitor); + fetch.setTimeout(this.timeout); + + fetchRes = fetch.call(); + } else { + // we can skip the fetch altogether + remoteUri = "local repository"; + fetchRes = null; + } monitor.update(1); // we check the updates to see which of the updated branches corresponds // to the remote branch name - AnyObjectId commitToMerge = null; + AnyObjectId commitToMerge; - Ref r = fetchRes.getAdvertisedRef(remoteBranchName); - if (r == null) - r = fetchRes.getAdvertisedRef(Constants.R_HEADS + remoteBranchName); - if (r == null) { - // TODO: we should be able to get the mapping also if nothing was - // updated by the fetch; for the time being, use the naming - // convention as fall back - String remoteTrackingBranch = Constants.R_REMOTES + remote + '/' - + branchName; + if (isRemote) { + Ref r = null; + if (fetchRes != null) { + r = fetchRes.getAdvertisedRef(remoteBranchName); + if (r == null) + r = fetchRes.getAdvertisedRef(Constants.R_HEADS + + remoteBranchName); + } + if (r == null) + throw new JGitInternalException(MessageFormat.format(JGitText + .get().couldNotGetAdvertisedRef, remoteBranchName)); + else + commitToMerge = r.getObjectId(); + } else { try { - commitToMerge = repo.resolve(remoteTrackingBranch); + commitToMerge = repo.resolve(remoteBranchName); } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfPullCommand, e); } - - } else - commitToMerge = r.getObjectId(); + } if (monitor.isCancelled()) throw new CanceledException(MessageFormat.format(