Browse Source

Add support for pull with --rebase and --no-rebase

Bug: 394501
Change-Id: I697e2fc82a46c03762111eb1de93e673a2643b4f
Signed-off-by: Chris Aniszczyk <zx@twitter.com>
tags/v2.2.0.201212191850-r
Mikael Karlsson 12 years ago
parent
commit
fa5231191d

+ 70
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java View File

@@ -44,6 +44,7 @@ package org.eclipse.jgit.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

@@ -58,11 +59,14 @@ import org.eclipse.jgit.api.MergeResult.MergeStatus;
import org.eclipse.jgit.api.RebaseResult.Status;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.RepositoryTestCase;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig;
@@ -226,6 +230,72 @@ public class PullCommandWithRebaseTest extends RepositoryTestCase {
.getRepository().getRepositoryState());
}

@Test
public void testPullFastForwardWithLocalCommitAndRebaseFlagSet() throws Exception {
final String SOURCE_COMMIT_MESSAGE = "Source commit message for rebase flag test";
final String TARGET_COMMIT_MESSAGE = "Target commit message for rebase flag test";

assertFalse(SOURCE_COMMIT_MESSAGE.equals(TARGET_COMMIT_MESSAGE));

final String SOURCE_FILE_CONTENTS = "Source change";
final String NEW_FILE_CONTENTS = "New file from target";

// make sure the config for target says we should pull with merge
// we will override this later with the setRebase method
StoredConfig targetConfig = dbTarget.getConfig();
targetConfig.setBoolean("branch", "master", "rebase", false);
targetConfig.save();

// create commit in source
writeToFile(sourceFile, SOURCE_FILE_CONTENTS);
source.add().addFilepattern(sourceFile.getName()).call();
source.commit().setMessage(SOURCE_COMMIT_MESSAGE).call();

// create commit in target, not conflicting with the new commit in source
File newFile = new File(dbTarget.getWorkTree().getPath() + "/newFile.txt");
writeToFile(newFile, NEW_FILE_CONTENTS);
target.add().addFilepattern(newFile.getName()).call();
target.commit().setMessage(TARGET_COMMIT_MESSAGE).call();

// verify that rebase is set to false in the config
assertFalse(targetConfig.getBoolean("branch", "master", "rebase", true));

// pull with rebase - local commit in target should be on top
PullResult pullResult = target.pull().setRebase(true).call();

// make sure pull is considered successful
assertTrue(pullResult.isSuccessful());

// verify rebase result is ok
RebaseResult rebaseResult = pullResult.getRebaseResult();
assertNotNull(rebaseResult);
assertNull(rebaseResult.getFailingPaths());
assertEquals(Status.OK, rebaseResult.getStatus());

// Get the HEAD and HEAD~1 commits
Repository targetRepo = target.getRepository();
RevWalk revWalk = new RevWalk(targetRepo);
ObjectId headId = targetRepo.resolve(Constants.HEAD);
RevCommit root = revWalk.parseCommit(headId);
revWalk.markStart(root);
// HEAD
RevCommit head = revWalk.next();
// HEAD~1
RevCommit beforeHead = revWalk.next();

// verify the commit message on the HEAD commit
assertEquals(TARGET_COMMIT_MESSAGE, head.getFullMessage());
// verify the commit just before HEAD
assertEquals(SOURCE_COMMIT_MESSAGE, beforeHead.getFullMessage());

// verify file states
assertFileContentsEqual(sourceFile, SOURCE_FILE_CONTENTS);
assertFileContentsEqual(newFile, NEW_FILE_CONTENTS);
// verify repository state
assertEquals(RepositoryState.SAFE, target
.getRepository().getRepositoryState());
}

@Override
@Before
public void setUp() throws Exception {

+ 48
- 4
org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java View File

@@ -80,6 +80,14 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> {

private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;

private PullRebaseMode pullRebaseMode = PullRebaseMode.USE_CONFIG;

private enum PullRebaseMode {
USE_CONFIG,
REBASE,
NO_REBASE
}

/**
* @param repo
*/
@@ -97,6 +105,28 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> {
return this;
}

/**
* Set if rebase should be used after fetching. If set to true, rebase is
* used instead of merge. This is equivalent to --rebase on the command line.
* <p/>
* If set to false, merge is used after fetching, overriding the configuration
* file. This is equivalent to --no-rebase on the command line.
* <p/>
* This setting overrides the settings in the configuration file.
* By default, the setting in the repository configuration file is used.
* <p/>
* A branch can be configured to use rebase by default.
* See branch.[name].rebase and branch.autosetuprebase.
*
* @param useRebase
* @return {@code this}
*/
public PullCommand setRebase(boolean useRebase) {
checkCallable();
pullRebaseMode = useRebase ? PullRebaseMode.REBASE : PullRebaseMode.NO_REBASE;
return this;
}

/**
* Executes the {@code Pull} command with all the options and parameters
* collected by the setter methods (e.g.
@@ -162,10 +192,24 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> {
String remoteBranchName = repoConfig.getString(
ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
ConfigConstants.CONFIG_KEY_MERGE);
// check if the branch is configured for pull-rebase
boolean doRebase = repoConfig.getBoolean(
ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
ConfigConstants.CONFIG_KEY_REBASE, false);

// determines whether rebase should be used after fetching
boolean doRebase = false;
switch (pullRebaseMode) {
case REBASE:
doRebase = true;
break;
case NO_REBASE:
doRebase = false;
break;
case USE_CONFIG:
default:
// check if the branch is configured for pull-rebase
doRebase = repoConfig.getBoolean(
ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
ConfigConstants.CONFIG_KEY_REBASE, false);
break;
}

if (remoteBranchName == null) {
String missingKey = ConfigConstants.CONFIG_BRANCH_SECTION + DOT

Loading…
Cancel
Save