in org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java [182:380]
public PullResult call() throws GitAPIException,
WrongRepositoryStateException, InvalidConfigurationException,
InvalidRemoteException, CanceledException,
RefNotFoundException, RefNotAdvertisedException, NoHeadException,
org.eclipse.jgit.api.errors.TransportException {
checkCallable();
monitor.beginTask(JGitText.get().pullTaskName, 2);
Config repoConfig = repo.getConfig();
String branchName = null;
try {
String fullBranch = repo.getFullBranch();
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()));
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) {
// fall back to default remote
remote = Constants.DEFAULT_REMOTE_NAME;
}
// determines whether rebase should be used after fetching
if (pullRebaseMode == null && branchName != null) {
pullRebaseMode = getRebaseMode(branchName, repoConfig);
}
final boolean isRemote = !remote.equals("."); //$NON-NLS-1$
String remoteUri;
FetchResult fetchRes;
if (isRemote) {
remoteUri = repoConfig.getString(
ConfigConstants.CONFIG_REMOTE_SECTION, 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));
}
if (monitor.isCancelled())
throw new CanceledException(MessageFormat.format(
JGitText.get().operationCanceled,
JGitText.get().pullTaskName));
FetchCommand fetch = new FetchCommand(repo).setRemote(remote)
.setProgressMonitor(monitor).setTagOpt(tagOption)
.setRecurseSubmodules(submoduleRecurseMode);
configure(fetch);
fetchRes = fetch.call();
} else {
// we can skip the fetch altogether
remoteUri = JGitText.get().localRepository;
fetchRes = null;
}
monitor.update(1);
if (monitor.isCancelled())
throw new CanceledException(MessageFormat.format(
JGitText.get().operationCanceled,
JGitText.get().pullTaskName));
// we check the updates to see which of the updated branches
// corresponds to the remote branch name
AnyObjectId commitToMerge;
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 RefNotAdvertisedException(MessageFormat.format(
JGitText.get().couldNotGetAdvertisedRef, remote,
remoteBranchName));
}
commitToMerge = r.getObjectId();
} else {
try {
commitToMerge = repo.resolve(remoteBranchName);
if (commitToMerge == null) {
throw new RefNotFoundException(MessageFormat.format(
JGitText.get().refNotResolved, remoteBranchName));
}
} catch (IOException e) {
throw new JGitInternalException(
JGitText.get().exceptionCaughtDuringExecutionOfPullCommand,
e);
}
}
String upstreamName = MessageFormat.format(
JGitText.get().upstreamBranchName,
Repository.shortenRefName(remoteBranchName), remoteUri);
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)
.setProgressMonitor(monitor)
.setUpstreamName(upstreamName)
.setOperation(Operation.BEGIN)
.setStrategy(strategy)
.setContentMergeStrategy(contentStrategy)
.setPreserveMerges(
pullRebaseMode == BranchRebaseMode.PRESERVE)
.call();
result = new PullResult(fetchRes, remote, rebaseRes);
} else {
MergeCommand merge = new MergeCommand(repo);
MergeResult mergeRes = merge.include(upstreamName, commitToMerge)
.setProgressMonitor(monitor)
.setStrategy(strategy)
.setContentMergeStrategy(contentStrategy)
.setFastForward(getFastForwardMode()).call();
monitor.update(1);
result = new PullResult(fetchRes, remote, mergeRes);
}
monitor.endTask();
return result;
}