@Override protected void save(@NotNull Collection<VirtualFile> rootsToSave) throws VcsException { LOG.info("saving " + rootsToSave); for (VirtualFile root : rootsToSave) { final String message = GitHandlerUtil.formatOperationName("Stashing changes from", root); LOG.info(message); final String oldProgressTitle = myProgressIndicator.getText(); myProgressIndicator.setText(message); GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) { LOG.error("Repository is null for root " + root); } else { GitCommandResult result = myGit.stashSave(repository, myStashMessage); if (result.success() && somethingWasStashed(result)) { myStashedRoots.add(root); } else { String error = "stash " + repository.getRoot() + ": " + result.getErrorOutputAsJoinedString(); if (!result.success()) { throw new VcsException(error); } else { LOG.warn(error); } } } myProgressIndicator.setText(oldProgressTitle); } }
/** * Returns true if the root was loaded with conflict. False is returned in all other cases: in the * case of success and in case of some other error. */ private boolean loadRoot(final VirtualFile root) { LOG.info("loadRoot " + root); myProgressIndicator.setText(GitHandlerUtil.formatOperationName("Unstashing changes to", root)); GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) { LOG.error("Repository is null for root " + root); return false; } GitSimpleEventDetector conflictDetector = new GitSimpleEventDetector(GitSimpleEventDetector.Event.MERGE_CONFLICT_ON_UNSTASH); GitCommandResult result = myGit.stashPop(repository, conflictDetector); VfsUtil.markDirtyAndRefresh(false, true, false, root); if (result.success()) { return false; } else if (conflictDetector.hasHappened()) { return true; } else { LOG.info("unstash failed " + result.getErrorOutputAsJoinedString()); GitUIUtil.notifyImportantError( myProject, "Couldn't unstash", "<br/>" + result.getErrorOutputAsHtmlString()); return false; } }
@Nullable protected GitRepository findRepository() { if (myRepository != null) { return myRepository; } myRepository = myGitRepositoryManager.getRepositoryForRoot(myContentRoot); return myRepository; }
@Nullable public static GitRepository getRepositoryForRootOrLogError( @NotNull Project project, @NotNull VirtualFile root) { GitRepositoryManager manager = getRepositoryManager(project); GitRepository repository = manager.getRepositoryForRoot(root); if (repository == null) { LOG.error("Repository is null for root " + root); } return repository; }
@Nullable @Override public String getCurrentBranch(@NotNull VirtualFile root) { GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) return null; String currentBranchName = repository.getCurrentBranchName(); if (currentBranchName == null && repository.getCurrentRevision() != null) { return "HEAD"; } return currentBranchName; }
private static void updateUntrackedFilesHolderOnFileAdd( @NotNull Project project, @NotNull VirtualFile root, @NotNull Collection<VirtualFile> addedFiles) { GitRepositoryManager manager = GitUtil.getRepositoryManager(project); if (manager == null) { return; } final GitRepository repository = manager.getRepositoryForRoot(root); if (repository != null) { repository.getUntrackedFilesHolder().remove(addedFiles); } }
/** * Scans the Git roots, selected for commit, for the root which is on a detached HEAD. Returns * null, if all repositories are on the branch. There might be several detached repositories, - * in that case only one is returned. This is because the situation is very rare, while it * requires a lot of additional effort of making a well-formed message. */ @Nullable private DetachedRoot getDetachedRoot() { GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(myPanel.getProject()); for (VirtualFile root : getSelectedRoots()) { GitRepository repository = repositoryManager.getRepositoryForRoot(root); if (repository == null) { continue; } if (!repository.isOnBranch()) { return new DetachedRoot(root, repository.isRebaseInProgress()); } } return null; }
@NotNull public static Collection<GitRepository> getRepositoriesFromRoots( @NotNull GitRepositoryManager repositoryManager, @NotNull Collection<VirtualFile> roots) { Collection<GitRepository> repositories = new ArrayList<GitRepository>(roots.size()); for (VirtualFile root : roots) { GitRepository repo = repositoryManager.getRepositoryForRoot(root); if (repo == null) { LOG.error("Repository not found for root " + root); } else { repositories.add(repo); } } return repositories; }
@NotNull public GitFetchResult fetch(@NotNull VirtualFile root, @NotNull String remoteName) { GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) { return logError("Repository can't be null for " + root, myRepositoryManager.toString()); } GitRemote remote = GitUtil.findRemoteByName(repository, remoteName); if (remote == null) { return logError("Couldn't find remote with the name " + remoteName, null); } String url = remote.getFirstUrl(); if (url == null) { return logError("URL is null for remote " + remote.getName(), null); } return fetchRemote(repository, remote, url); }
/** * Parse changes from lines * * @param root the git root * @return a set of unmerged files * @throws com.intellij.openapi.vcs.VcsException if the input format does not matches expected * format */ private List<VirtualFile> unmergedFiles(final VirtualFile root) throws VcsException { GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) { LOG.error("Repository not found for root " + root); return Collections.emptyList(); } GitCommandResult result = myGit.getUnmergedFiles(repository); if (!result.success()) { throw new VcsException(result.getErrorOutputAsJoinedString()); } String output = StringUtil.join(result.getOutput(), "\n"); HashSet<String> unmergedPaths = ContainerUtil.newHashSet(); for (StringScanner s = new StringScanner(output); s.hasMoreData(); ) { if (s.isEol()) { s.nextLine(); continue; } s.boundedToken('\t'); String relative = s.line(); unmergedPaths.add(GitUtil.unescapePath(relative)); } if (unmergedPaths.size() == 0) { return Collections.emptyList(); } else { List<File> files = ContainerUtil.map( unmergedPaths, new Function<String, File>() { @Override public File fun(String path) { return new File(root.getPath(), path); } }); return sortVirtualFilesByPresentation(findVirtualFilesWithRefresh(files)); } }
@Override public void actionPerformed(AnActionEvent e) { Data data = Data.collect(e); if (!data.isValid()) { return; } List<VcsFullCommitDetails> details = data.log.getSelectedDetails(); if (details.size() != 1) { return; } VcsFullCommitDetails commit = details.get(0); GitRepositoryManager repositoryManager = ServiceManager.getService(data.project, GitRepositoryManager.class); final GitRepository repository = repositoryManager.getRepositoryForRoot(commit.getRoot()); if (repository == null) { DvcsUtil.noVcsRepositoryForRoot( LOG, commit.getRoot(), data.project, repositoryManager, GitVcs.getInstance(data.project)); return; } actionPerformed(repository, commit); }
@NotNull @Override public DetailedLogData readFirstBlock( @NotNull VirtualFile root, @NotNull Requirements requirements) throws VcsException { if (!isRepositoryReady(root)) { return LogDataImpl.empty(); } GitRepository repository = ObjectUtils.assertNotNull(myRepositoryManager.getRepositoryForRoot(root)); // need to query more to sort them manually; this doesn't affect performance: it is equal for // -1000 and -2000 int commitCount = requirements.getCommitCount() * 2; String[] params = new String[] {"HEAD", "--branches", "--remotes", "--max-count=" + commitCount}; // NB: not specifying --tags, because it introduces great slowdown if there are many tags, // but makes sense only if there are heads without branch or HEAD labels (rare case). Such cases // are partially handled below. boolean refresh = requirements instanceof VcsLogProviderRequirementsEx && ((VcsLogProviderRequirementsEx) requirements).isRefresh(); DetailedLogData data = GitHistoryUtils.loadMetadata(myProject, root, true, params); Set<VcsRef> safeRefs = data.getRefs(); Set<VcsRef> allRefs = new OpenTHashSet<VcsRef>(safeRefs, DONT_CONSIDER_SHA); Set<VcsRef> branches = readBranches(repository); addNewElements(allRefs, branches); Collection<VcsCommitMetadata> allDetails; Set<String> currentTagNames = null; DetailedLogData commitsFromTags = null; if (!refresh) { allDetails = data.getCommits(); } else { // on refresh: get new tags, which point to commits not from the first block; then get // history, walking down just from these tags // on init: just ignore such tagged-only branches. The price for speed-up. VcsLogProviderRequirementsEx rex = (VcsLogProviderRequirementsEx) requirements; currentTagNames = readCurrentTagNames(root); addOldStillExistingTags(allRefs, currentTagNames, rex.getPreviousRefs()); allDetails = newHashSet(data.getCommits()); Set<String> previousTags = newHashSet(ContainerUtil.mapNotNull(rex.getPreviousRefs(), GET_TAG_NAME)); Set<String> safeTags = newHashSet(ContainerUtil.mapNotNull(safeRefs, GET_TAG_NAME)); Set<String> newUnmatchedTags = remove(currentTagNames, previousTags, safeTags); if (!newUnmatchedTags.isEmpty()) { commitsFromTags = loadSomeCommitsOnTaggedBranches(root, commitCount, newUnmatchedTags); addNewElements(allDetails, commitsFromTags.getCommits()); addNewElements(allRefs, commitsFromTags.getRefs()); } } StopWatch sw = StopWatch.start("sorting commits in " + root.getName()); List<VcsCommitMetadata> sortedCommits = VcsLogSorter.sortByDateTopoOrder(allDetails); sortedCommits = sortedCommits.subList(0, Math.min(sortedCommits.size(), requirements.getCommitCount())); sw.report(); if (LOG.isDebugEnabled()) { validateDataAndReportError( root, allRefs, sortedCommits, data, branches, currentTagNames, commitsFromTags); } return new LogDataImpl(allRefs, sortedCommits); }
@Nullable private GitRepository getRepository(@NotNull VirtualFile root) { return myRepositoryManager.getRepositoryForRoot(root); }
public void checkGitUrl(final T settings) throws ConfigurationException { if (!(myDeploymentSource instanceof ModuleDeploymentSource)) { return; } ModuleDeploymentSource moduleSource = (ModuleDeploymentSource) myDeploymentSource; Module module = moduleSource.getModule(); if (module == null) { return; } File contentRootFile = myDeploymentSource.getFile(); if (contentRootFile == null) { return; } final Project project = module.getProject(); if (myGitRepositoryManager == null) { myGitRepositoryManager = GitUtil.getRepositoryManager(project); } VirtualFile contentRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(contentRootFile); if (contentRoot == null) { return; } GitRepository repository = myGitRepositoryManager.getRepositoryForRoot(contentRoot); if (repository == null) { return; } String expectedName = settings.getDeploymentSourceName(myDeploymentSource); List<String> appNames = myDetector.collectApplicationNames(repository); if (appNames.isEmpty() || appNames.contains(expectedName)) { return; } RuntimeConfigurationWarning warning = new RuntimeConfigurationWarning( "Cloud Git URL found in repository, but it doesn't match the run configuration"); warning.setQuickFix( new Runnable() { @Override public void run() { CloudGitApplication application = new CloudConnectionTask<CloudGitApplication, SC, T, SR>( project, "Searching for application", myServer) { @Override protected CloudGitApplication run(SR serverRuntime) throws ServerRuntimeException { CloudGitDeploymentRuntime deploymentRuntime = (CloudGitDeploymentRuntime) serverRuntime.createDeploymentRuntime( myDeploymentSource, settings, project); return deploymentRuntime.findApplication4Repository(); } }.performSync(); if (application == null) { Messages.showErrorDialog( mySettingsEditor.getComponent(), "No application matching repository URL(s) found in account"); } else { T fixedSettings = mySettingsEditor.getFactory().create(); fixedSettings.setDefaultDeploymentName(false); fixedSettings.setDeploymentName(application.getName()); mySettingsEditor.resetFrom(fixedSettings); } } }); throw warning; }
@Nullable private GitRepository getRepository(@NotNull VirtualFile root) { myRepositoryManager.waitUntilInitialized(); return myRepositoryManager.getRepositoryForRoot(root); }