Allow programmatic remote configuration for PullCommand

Also imply remoteBranchName to match current branch name if it wasn't
configured in branch configuration.

Bug: 424812
Change-Id: Id852cedaefb2a537b6aa3c330b9861efad052f11
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Matthias Sohn 2014-01-07 10:15:14 +01:00
parent 7bb7299e8a
commit 1eae309723
2 changed files with 133 additions and 16 deletions

View File

@ -232,6 +232,71 @@ public void testPullEmptyRepository() throws Exception {
Git.wrap(empty).pull().call();
}
@Test
public void testPullMergeProgrammaticConfiguration() throws Exception {
// create another commit on another branch in source
source.checkout().setCreateBranch(true).setName("other").call();
sourceFile = new File(db.getWorkTree(), "file2.txt");
writeToFile(sourceFile, "content");
source.add().addFilepattern("file2.txt").call();
RevCommit sourceCommit = source.commit()
.setMessage("source commit on branch other").call();
File targetFile2 = new File(dbTarget.getWorkTree(), "OtherFile.txt");
writeToFile(targetFile2, "Unconflicting change");
target.add().addFilepattern("OtherFile.txt").call();
RevCommit targetCommit = target.commit()
.setMessage("Unconflicting change in local").call();
PullResult res = target.pull().setRemote("origin")
.setRemoteBranchName("other")
.setRebase(false).call();
MergeResult mergeResult = res.getMergeResult();
ObjectId[] mergedCommits = mergeResult.getMergedCommits();
assertEquals(targetCommit.getId(), mergedCommits[0]);
assertEquals(sourceCommit.getId(), mergedCommits[1]);
RevCommit mergeCommit = new RevWalk(dbTarget).parseCommit(mergeResult
.getNewHead());
String message = "Merge branch 'other' of "
+ db.getWorkTree().getAbsolutePath();
assertEquals(message, mergeCommit.getShortMessage());
}
@Test
public void testPullMergeProgrammaticConfigurationImpliedTargetBranch()
throws Exception {
// create another commit on another branch in source
source.checkout().setCreateBranch(true).setName("other").call();
sourceFile = new File(db.getWorkTree(), "file2.txt");
writeToFile(sourceFile, "content");
source.add().addFilepattern("file2.txt").call();
RevCommit sourceCommit = source.commit()
.setMessage("source commit on branch other").call();
target.checkout().setCreateBranch(true).setName("other").call();
File targetFile2 = new File(dbTarget.getWorkTree(), "OtherFile.txt");
writeToFile(targetFile2, "Unconflicting change");
target.add().addFilepattern("OtherFile.txt").call();
RevCommit targetCommit = target.commit()
.setMessage("Unconflicting change in local").call();
// the source branch "other" matching the target branch should be
// implied
PullResult res = target.pull().setRemote("origin").setRebase(false)
.call();
MergeResult mergeResult = res.getMergeResult();
ObjectId[] mergedCommits = mergeResult.getMergedCommits();
assertEquals(targetCommit.getId(), mergedCommits[0]);
assertEquals(sourceCommit.getId(), mergedCommits[1]);
RevCommit mergeCommit = new RevWalk(dbTarget).parseCommit(mergeResult
.getNewHead());
String message = "Merge branch 'other' of "
+ db.getWorkTree().getAbsolutePath() + " into other";
assertEquals(message, mergeCommit.getShortMessage());
}
@Override
@Before
public void setUp() throws Exception {

View File

@ -82,6 +82,10 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> {
private PullRebaseMode pullRebaseMode = PullRebaseMode.USE_CONFIG;
private String remote;
private String remoteBranchName;
private enum PullRebaseMode {
USE_CONFIG,
REBASE,
@ -177,21 +181,24 @@ public PullResult call() throws GitAPIException,
JGitText.get().cannotPullOnARepoWithState, repo
.getRepositoryState().name()));
// get the configured remote for the currently checked out branch
// stored in configuration key branch.<branch name>.remote
Config repoConfig = repo.getConfig();
String remote = repoConfig.getString(
ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
ConfigConstants.CONFIG_KEY_REMOTE);
if (remote == null) {
// get the configured remote for the currently checked out branch
// stored in configuration key branch.<branch name>.remote
remote = repoConfig.getString(
ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
ConfigConstants.CONFIG_KEY_REMOTE);
}
if (remote == null)
// fall back to default remote
remote = Constants.DEFAULT_REMOTE_NAME;
// get the name of the branch in the remote repository
// stored in configuration key branch.<branch name>.merge
String remoteBranchName = repoConfig.getString(
ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
ConfigConstants.CONFIG_KEY_MERGE);
if (remoteBranchName == null)
// get the name of the branch in the remote repository
// stored in configuration key branch.<branch name>.merge
remoteBranchName = repoConfig.getString(
ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
ConfigConstants.CONFIG_KEY_MERGE);
// determines whether rebase should be used after fetching
boolean doRebase = false;
@ -211,12 +218,8 @@ public PullResult call() throws GitAPIException,
break;
}
if (remoteBranchName == null) {
String missingKey = ConfigConstants.CONFIG_BRANCH_SECTION + DOT
+ branchName + DOT + ConfigConstants.CONFIG_KEY_MERGE;
throw new InvalidConfigurationException(MessageFormat.format(
JGitText.get().missingConfigurationForKey, missingKey));
}
if (remoteBranchName == null)
remoteBranchName = branchName;
final boolean isRemote = !remote.equals("."); //$NON-NLS-1$
String remoteUri;
@ -309,4 +312,53 @@ public PullResult call() throws GitAPIException,
return result;
}
/**
* The remote (uri or name) to be used for the pull operation. If no remote
* is set, the branch's configuration will be used. If the branch
* configuration is missing the default value of
* <code>Constants.DEFAULT_REMOTE_NAME</code> will be used.
*
* @see Constants#DEFAULT_REMOTE_NAME
* @param remote
* @return {@code this}
* @since 3.3
*/
public PullCommand setRemote(String remote) {
checkCallable();
this.remote = remote;
return this;
}
/**
* The remote branch name to be used for the pull operation. If no
* remoteBranchName is set, the branch's configuration will be used. If the
* branch configuration is missing the remote branch with the same name as
* the current branch is used.
*
* @param remoteBranchName
* @return {@code this}
* @since 3.3
*/
public PullCommand setRemoteBranchName(String remoteBranchName) {
checkCallable();
this.remoteBranchName = remoteBranchName;
return this;
}
/**
* @return the remote used for the pull operation if it was set explicitly
* @since 3.3
*/
public String getRemote() {
return remote;
}
/**
* @return the remote branch name used for the pull operation if it was set
* explicitly
* @since 3.3
*/
public String getRemoteBranchName() {
return remoteBranchName;
}
}