in plugin/src/com/microsoft/alm/plugin/idea/git/ui/simplecheckout/SimpleCheckoutModel.java [166:282]
public void cloneRepo() {
final ModelValidationInfo validationInfo = validate();
if (validationInfo == null) {
final Task.Backgroundable createCloneTask = new Task.Backgroundable(project, TfPluginBundle.message(TfPluginBundle.KEY_CHECKOUT_DIALOG_TITLE),
true, PerformInBackgroundOption.DEAF) {
final AtomicBoolean cloneResult = new AtomicBoolean();
@Override
public void run(@NotNull final ProgressIndicator progressIndicator) {
progressIndicator.setText(TfPluginBundle.message(TfPluginBundle.KEY_CHECKOUT_DIALOG_TITLE));
// get context from manager, and store in active context
final ServerContext context = ServerContextManager.getInstance().getUpdatedContext(gitUrl, true);
if (context == null) {
logger.warn("No context could be found");
VcsNotifier.getInstance(project).notifyError(TfPluginBundle.message(TfPluginBundle.KEY_CHECKOUT_ERRORS_AUTHENTICATION_FAILED_TITLE), TfPluginBundle.message(TfPluginBundle.KEY_ERRORS_AUTH_NOT_SUCCESSFUL, gitUrl));
return;
}
final String gitRepositoryStr = context.getUsableGitUrl();
final Git git = ServiceManager.getService(Git.class);
logger.info("Cloning repo " + gitRepositoryStr);
cloneResult.set(git4idea.checkout.GitCheckoutProvider.doClone(project, git, getDirectoryName(), getParentDirectory(), gitRepositoryStr));
}
@Override
public void onSuccess() {
logger.info("Simple clone was a success");
// if clone was successful then complete the checkout process which gives the option to open the project
if (cloneResult.get()) {
final VirtualFile destinationParent = LocalFileSystem.getInstance().findFileByIoFile(
new File(getParentDirectory()));
final File projectDirectory = new File(parentDirectory, directoryName);
DvcsUtil.addMappingIfSubRoot(project, FileUtil.join(new String[]{parentDirectory, directoryName}), "Git");
destinationParent.refresh(true, true, new Runnable() {
public void run() {
if (project.isOpen() && !project.isDisposed() && !project.isDefault()) {
VcsDirtyScopeManager mgr = VcsDirtyScopeManager.getInstance(project);
mgr.fileDirty(destinationParent);
}
}
});
listener.directoryCheckedOut(projectDirectory, GitVcs.getKey());
listener.checkoutCompleted();
// the project has changed since a new project was created above during the directoryCheckedOut process
// finding the new project based on the repo path
final Project currentProject = IdeaHelper.getCurrentProject();
// check if ref is not master and if currentProject is not null
// if currentProject is null that means the user chose not to create the project so not checking the branch out
if (StringUtils.isNotEmpty(ref) && !StringUtils.equals(ref, MASTER_BRANCH) && currentProject != null) {
logger.info("Non-master branch detected to checkout");
checkoutBranch(ref, currentProject, projectDirectory);
}
}
}
private void checkoutBranch(final String ref, final Project lastOpenedProject, final File projectDirectory) {
// adds a post initialization step to the project to checkout the given branch
final ProjectLevelVcsManagerImpl manager = (ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(lastOpenedProject);
// add step to refresh the root mapping so the new root is found for the repo
// TODO: refactor to use existing call instead of calling twice. Current call happens too late currently
// TODO: so that's why we need to call this beforehand so we can checkout the branch
manager.addInitializationRequest(VcsInitObject.MAPPINGS, new Runnable() {
@Override
public void run() {
manager.setDirectoryMapping(projectDirectory.getPath(), "Git");
manager.fireDirectoryMappingsChanged();
}
});
// step to checkout the desired branch
manager.addInitializationRequest(VcsInitObject.AFTER_COMMON, new DumbAwareRunnable() {
public void run() {
final GitRepositoryManager gitRepositoryManager = ServiceManager.getService(lastOpenedProject, GitRepositoryManager.class);
ArgumentHelper.checkNotNull(gitRepositoryManager, "GitRepositoryManager");
ArgumentHelper.checkNotNullOrEmpty(gitRepositoryManager.getRepositories(), "gitRepositoryManager.getRepositories()");
// TODO: use more direct manner to get repo but right now due to timing we can't
final GitRepository gitRepository = gitRepositoryManager.getRepositories().get(0);
ArgumentHelper.checkNotNull(gitRepository, "GitRepository");
String fullRefName = StringUtils.EMPTY;
// find remote red name from given name
for (final GitRemoteBranch remoteBranch : gitRepository.getInfo().getRemoteBranches()) {
final String remoteBranchName = remoteBranch.getName().replaceFirst(remoteBranch.getRemote().getName() + "/", StringUtils.EMPTY);
if (ref.equals(remoteBranchName)) {
fullRefName = remoteBranch.getName();
}
}
if (StringUtils.isNotEmpty(fullRefName)) {
final String remoteRef = fullRefName;
// Checking out a branch using the brancher has to start on the UI thread but moves to the background
IdeaHelper.runOnUIThread(new Runnable() {
@Override
public void run() {
logger.info("Checking out branch " + remoteRef);
final GitBrancher brancher = ServiceManager.getService(lastOpenedProject, GitBrancher.class);
brancher.checkoutNewBranchStartingFrom(ref, remoteRef,
Collections.singletonList(gitRepository), null);
}
});
} else {
throw new IllegalArgumentException(String.format("Ref %s was not found remotely so could not be checked out.", fullRefName));
}
}
});
}
};
createCloneTask.queue();
}
}