Support pull on detached HEAD
Bug: 485396 Change-Id: I82be09385c9b0bcc0054fea5a9cb9d178a41e278 Signed-off-by: Mickael Istria <mistria@redhat.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
parent
8f7d0a4fbe
commit
5b84e25fa3
|
@ -61,6 +61,7 @@
|
|||
import org.eclipse.jgit.lib.ConfigConstants;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.RepositoryState;
|
||||
import org.eclipse.jgit.lib.StoredConfig;
|
||||
|
@ -147,6 +148,57 @@ public void testPullFastForwardWithBranchInSource() throws Exception {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPullFastForwardDetachedHead() throws Exception {
|
||||
Repository repository = source.getRepository();
|
||||
writeToFile(sourceFile, "2nd commit");
|
||||
source.add().addFilepattern("SomeFile.txt").call();
|
||||
source.commit().setMessage("2nd commit").call();
|
||||
|
||||
try (RevWalk revWalk = new RevWalk(repository)) {
|
||||
// git checkout HEAD^
|
||||
String initialBranch = repository.getBranch();
|
||||
Ref initialRef = repository.findRef(Constants.HEAD);
|
||||
RevCommit initialCommit = revWalk
|
||||
.parseCommit(initialRef.getObjectId());
|
||||
assertEquals("this test need linear history", 1,
|
||||
initialCommit.getParentCount());
|
||||
source.checkout().setName(initialCommit.getParent(0).getName())
|
||||
.call();
|
||||
assertFalse("expected detached HEAD",
|
||||
repository.getFullBranch().startsWith(Constants.R_HEADS));
|
||||
|
||||
// change and commit another file
|
||||
File otherFile = new File(sourceFile.getParentFile(),
|
||||
System.currentTimeMillis() + ".tst");
|
||||
writeToFile(otherFile, "other 2nd commit");
|
||||
source.add().addFilepattern(otherFile.getName()).call();
|
||||
RevCommit newCommit = source.commit().setMessage("other 2nd commit")
|
||||
.call();
|
||||
|
||||
// git pull --rebase initialBranch
|
||||
source.pull().setRebase(true).setRemote(".")
|
||||
.setRemoteBranchName(initialBranch)
|
||||
.call();
|
||||
|
||||
assertEquals(RepositoryState.SAFE,
|
||||
source.getRepository().getRepositoryState());
|
||||
Ref head = source.getRepository().findRef(Constants.HEAD);
|
||||
RevCommit headCommit = revWalk.parseCommit(head.getObjectId());
|
||||
|
||||
// HEAD^ == initialCommit, no merge commit
|
||||
assertEquals(1, headCommit.getParentCount());
|
||||
assertEquals(initialCommit, headCommit.getParent(0));
|
||||
|
||||
// both contributions for both commits are available
|
||||
assertFileContentsEqual(sourceFile, "2nd commit");
|
||||
assertFileContentsEqual(otherFile, "other 2nd commit");
|
||||
// HEAD has same message as rebased commit
|
||||
assertEquals(newCommit.getShortMessage(),
|
||||
headCommit.getShortMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPullConflict() throws Exception {
|
||||
PullResult res = target.pull().call();
|
||||
|
|
|
@ -203,62 +203,63 @@ public PullCommand setRebase(BranchRebaseMode rebaseMode) {
|
|||
@Override
|
||||
public PullResult call() throws GitAPIException,
|
||||
WrongRepositoryStateException, InvalidConfigurationException,
|
||||
DetachedHeadException, InvalidRemoteException, CanceledException,
|
||||
InvalidRemoteException, CanceledException,
|
||||
RefNotFoundException, RefNotAdvertisedException, NoHeadException,
|
||||
org.eclipse.jgit.api.errors.TransportException {
|
||||
checkCallable();
|
||||
|
||||
monitor.beginTask(JGitText.get().pullTaskName, 2);
|
||||
Config repoConfig = repo.getConfig();
|
||||
|
||||
String branchName;
|
||||
String branchName = null;
|
||||
try {
|
||||
String fullBranch = repo.getFullBranch();
|
||||
if (fullBranch == null)
|
||||
throw new NoHeadException(
|
||||
JGitText.get().pullOnRepoWithoutHEADCurrentlyNotSupported);
|
||||
if (!fullBranch.startsWith(Constants.R_HEADS)) {
|
||||
// we can not pull if HEAD is detached and branch is not
|
||||
// specified explicitly
|
||||
throw new DetachedHeadException();
|
||||
}
|
||||
if (fullBranch != null
|
||||
&& fullBranch.startsWith(Constants.R_HEADS)) {
|
||||
branchName = fullBranch.substring(Constants.R_HEADS.length());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new JGitInternalException(
|
||||
JGitText.get().exceptionCaughtDuringExecutionOfPullCommand,
|
||||
e);
|
||||
}
|
||||
if (remoteBranchName == null && branchName != 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);
|
||||
}
|
||||
if (remoteBranchName == null) {
|
||||
remoteBranchName = branchName;
|
||||
}
|
||||
if (remoteBranchName == null) {
|
||||
throw new NoHeadException(
|
||||
JGitText.get().cannotCheckoutFromUnbornBranch);
|
||||
}
|
||||
|
||||
if (!repo.getRepositoryState().equals(RepositoryState.SAFE))
|
||||
throw new WrongRepositoryStateException(MessageFormat.format(
|
||||
JGitText.get().cannotPullOnARepoWithState, repo
|
||||
.getRepositoryState().name()));
|
||||
|
||||
Config repoConfig = repo.getConfig();
|
||||
if (remote == null) {
|
||||
if (remote == null && branchName != 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)
|
||||
if (remote == null) {
|
||||
// fall back to default remote
|
||||
remote = Constants.DEFAULT_REMOTE_NAME;
|
||||
|
||||
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
|
||||
if (pullRebaseMode == null) {
|
||||
if (pullRebaseMode == null && branchName != null) {
|
||||
pullRebaseMode = getRebaseMode(branchName, repoConfig);
|
||||
}
|
||||
|
||||
if (remoteBranchName == null)
|
||||
remoteBranchName = branchName;
|
||||
|
||||
final boolean isRemote = !remote.equals("."); //$NON-NLS-1$
|
||||
String remoteUri;
|
||||
|
|
Loading…
Reference in New Issue