diff options
Diffstat (limited to 'plugins/git4idea/src')
21 files changed, 303 insertions, 327 deletions
diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index 4286aee1536b..5f56de5674e1 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -18,6 +18,8 @@ package git4idea; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; +import com.intellij.ide.file.BatchFileChangeListener; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; @@ -43,6 +45,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.io.storage.HeavyProcessLatch; import com.intellij.util.ui.UIUtil; import com.intellij.vcsUtil.VcsFileUtil; import com.intellij.vcsUtil.VcsUtil; @@ -1010,4 +1013,15 @@ public class GitUtil { builder.setTitle(title); builder.show(); } + + public static void workingTreeChangeStarted(@NotNull Project project) { + HeavyProcessLatch.INSTANCE.processStarted(); + ApplicationManager.getApplication().getMessageBus().syncPublisher(BatchFileChangeListener.TOPIC).batchChangeStarted(project); + } + + public static void workingTreeChangeFinished(@NotNull Project project) { + HeavyProcessLatch.INSTANCE.processFinished(); + ApplicationManager.getApplication().getMessageBus().syncPublisher(BatchFileChangeListener.TOPIC).batchChangeCompleted(project); + } + } diff --git a/plugins/git4idea/src/git4idea/actions/GitMergeAction.java b/plugins/git4idea/src/git4idea/actions/GitMergeAction.java index 1d46335cc1b1..e8bc37929a0d 100644 --- a/plugins/git4idea/src/git4idea/actions/GitMergeAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitMergeAction.java @@ -81,27 +81,34 @@ abstract class GitMergeAction extends GitRepositoryAction { final Git git = ServiceManager.getService(Git.class); final GitLocalChangesWouldBeOverwrittenDetector localChangesDetector = new GitLocalChangesWouldBeOverwrittenDetector(selectedRoot, MERGE); - final GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = + final GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(selectedRoot); - GitCommandResult result = git.runCommand(new Computable<GitLineHandler>() { - @Override - public GitLineHandler compute() { - GitLineHandler handler = handlerProvider.compute(); - handler.addLineListener(localChangesDetector); - handler.addLineListener(untrackedFilesDetector); - return handler; - } - }); - affectedRoots.add(selectedRoot); - GitRepository repository = repositoryManager.getRepositoryForRoot(selectedRoot); - assert repository != null : "Repository can't be null for root " + selectedRoot; - String revision = repository.getCurrentRevision(); - if (revision == null) { - return; + GitUtil.workingTreeChangeStarted(project); + try { + GitCommandResult result = git.runCommand(new Computable<GitLineHandler>() { + @Override + public GitLineHandler compute() { + GitLineHandler handler = handlerProvider.compute(); + handler.addLineListener(localChangesDetector); + handler.addLineListener(untrackedFilesDetector); + return handler; + } + }); + affectedRoots.add(selectedRoot); + + GitRepository repository = repositoryManager.getRepositoryForRoot(selectedRoot); + assert repository != null : "Repository can't be null for root " + selectedRoot; + String revision = repository.getCurrentRevision(); + if (revision == null) { + return; + } + final GitRevisionNumber currentRev = new GitRevisionNumber(revision); + handleResult(result, project, localChangesDetector, untrackedFilesDetector, repository, currentRev, affectedRoots, beforeLabel); + } + finally { + GitUtil.workingTreeChangeFinished(project); } - final GitRevisionNumber currentRev = new GitRevisionNumber(revision); - handleResult(result, project, localChangesDetector, untrackedFilesDetector, repository, currentRev, affectedRoots, beforeLabel); } }.queue(); diff --git a/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.java b/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.java index 5b56884400ab..a3c4497e4dce 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.java +++ b/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; +import git4idea.GitUtil; import git4idea.commands.GitCommand; import git4idea.commands.GitHandlerUtil; import git4idea.commands.GitSimpleHandler; @@ -74,7 +75,13 @@ public class GitRebaseAbort extends GitRepositoryAction { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.REBASE); h.setStdoutSuppressed(false); h.addParameters("--abort"); - GitHandlerUtil.doSynchronously(h, getActionName(), h.printableCommandLine()); + GitUtil.workingTreeChangeStarted(project); + try { + GitHandlerUtil.doSynchronously(h, getActionName(), h.printableCommandLine()); + } + finally { + GitUtil.workingTreeChangeFinished(project); + } } /** diff --git a/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java b/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java index c69bfb6c7547..912dd0ba350f 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java +++ b/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java @@ -64,11 +64,17 @@ public abstract class GitRebaseActionBase extends GitRepositoryAction { task.executeInBackground(false, new GitTaskResultHandlerAdapter() { @Override protected void run(GitTaskResult taskResult) { - editor.close(); - GitRepositoryManager manager = GitUtil.getRepositoryManager(project); - manager.updateRepository(root); - root.refresh(false, true); - notifyAboutErrorResult(taskResult, resultListener, exceptions, project); + GitUtil.workingTreeChangeStarted(project); + try { + editor.close(); + GitRepositoryManager manager = GitUtil.getRepositoryManager(project); + manager.updateRepository(root); + root.refresh(false, true); + notifyAboutErrorResult(taskResult, resultListener, exceptions, project); + } + finally { + GitUtil.workingTreeChangeFinished(project); + } } }); } diff --git a/plugins/git4idea/src/git4idea/actions/GitResetHead.java b/plugins/git4idea/src/git4idea/actions/GitResetHead.java index d2278a2ed511..fd186b80e9e1 100644 --- a/plugins/git4idea/src/git4idea/actions/GitResetHead.java +++ b/plugins/git4idea/src/git4idea/actions/GitResetHead.java @@ -56,7 +56,13 @@ public class GitResetHead extends GitRepositoryAction { } GitLineHandler h = d.handler(); affectedRoots.add(d.getGitRoot()); - GitHandlerUtil.doSynchronously(h, GitBundle.getString("resetting.title"), h.printableCommandLine()); + GitUtil.workingTreeChangeStarted(project); + try { + GitHandlerUtil.doSynchronously(h, GitBundle.getString("resetting.title"), h.printableCommandLine()); + } + finally { + GitUtil.workingTreeChangeFinished(project); + } GitRepositoryManager manager = GitUtil.getRepositoryManager(project); manager.updateRepository(d.getGitRoot()); } diff --git a/plugins/git4idea/src/git4idea/actions/GitStash.java b/plugins/git4idea/src/git4idea/actions/GitStash.java index f23169708f38..b16c948b61c2 100644 --- a/plugins/git4idea/src/git4idea/actions/GitStash.java +++ b/plugins/git4idea/src/git4idea/actions/GitStash.java @@ -21,6 +21,7 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitPlatformFacade; +import git4idea.GitUtil; import git4idea.commands.GitHandlerUtil; import git4idea.commands.GitLineHandler; import git4idea.i18n.GitBundle; @@ -53,7 +54,13 @@ public class GitStash extends GitRepositoryAction { VirtualFile root = d.getGitRoot(); affectedRoots.add(root); final GitLineHandler h = d.handler(); - GitHandlerUtil.doSynchronously(h, GitBundle.getString("stashing.title"), h.printableCommandLine()); + GitUtil.workingTreeChangeStarted(project); + try { + GitHandlerUtil.doSynchronously(h, GitBundle.getString("stashing.title"), h.printableCommandLine()); + } + finally { + GitUtil.workingTreeChangeFinished(project); + } ServiceManager.getService(project, GitPlatformFacade.class).hardRefresh(root); } diff --git a/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java b/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java index d49dc15827b7..2441bf7d46cf 100644 --- a/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java +++ b/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java @@ -64,40 +64,46 @@ class GitCheckoutOperation extends GitBranchOperation { protected void execute() { saveAllDocuments(); boolean fatalErrorHappened = false; - while (hasMoreRepositories() && !fatalErrorHappened) { - final GitRepository repository = next(); - - VirtualFile root = repository.getRoot(); - GitLocalChangesWouldBeOverwrittenDetector localChangesDetector = - new GitLocalChangesWouldBeOverwrittenDetector(root, GitLocalChangesWouldBeOverwrittenDetector.Operation.CHECKOUT); - GitSimpleEventDetector unmergedFiles = new GitSimpleEventDetector(GitSimpleEventDetector.Event.UNMERGED_PREVENTING_CHECKOUT); - GitUntrackedFilesOverwrittenByOperationDetector untrackedOverwrittenByCheckout = - new GitUntrackedFilesOverwrittenByOperationDetector(root); - - GitCommandResult result = myGit.checkout(repository, myStartPointReference, myNewBranch, false, - localChangesDetector, unmergedFiles, untrackedOverwrittenByCheckout); - if (result.success()) { - refresh(repository); - markSuccessful(repository); - } - else if (unmergedFiles.hasHappened()) { - fatalUnmergedFilesError(); - fatalErrorHappened = true; - } - else if (localChangesDetector.wasMessageDetected()) { - boolean smartCheckoutSucceeded = smartCheckoutOrNotify(repository, localChangesDetector); - if (!smartCheckoutSucceeded) { + GitUtil.workingTreeChangeStarted(myProject); + try { + while (hasMoreRepositories() && !fatalErrorHappened) { + final GitRepository repository = next(); + + VirtualFile root = repository.getRoot(); + GitLocalChangesWouldBeOverwrittenDetector localChangesDetector = + new GitLocalChangesWouldBeOverwrittenDetector(root, GitLocalChangesWouldBeOverwrittenDetector.Operation.CHECKOUT); + GitSimpleEventDetector unmergedFiles = new GitSimpleEventDetector(GitSimpleEventDetector.Event.UNMERGED_PREVENTING_CHECKOUT); + GitUntrackedFilesOverwrittenByOperationDetector untrackedOverwrittenByCheckout = + new GitUntrackedFilesOverwrittenByOperationDetector(root); + + GitCommandResult result = myGit.checkout(repository, myStartPointReference, myNewBranch, false, + localChangesDetector, unmergedFiles, untrackedOverwrittenByCheckout); + if (result.success()) { + refresh(repository); + markSuccessful(repository); + } + else if (unmergedFiles.hasHappened()) { + fatalUnmergedFilesError(); + fatalErrorHappened = true; + } + else if (localChangesDetector.wasMessageDetected()) { + boolean smartCheckoutSucceeded = smartCheckoutOrNotify(repository, localChangesDetector); + if (!smartCheckoutSucceeded) { + fatalErrorHappened = true; + } + } + else if (untrackedOverwrittenByCheckout.wasMessageDetected()) { + fatalUntrackedFilesError(repository.getRoot(), untrackedOverwrittenByCheckout.getRelativeFilePaths()); + fatalErrorHappened = true; + } + else { + fatalError(getCommonErrorTitle(), result.getErrorOutputAsJoinedString()); fatalErrorHappened = true; } } - else if (untrackedOverwrittenByCheckout.wasMessageDetected()) { - fatalUntrackedFilesError(repository.getRoot(), untrackedOverwrittenByCheckout.getRelativeFilePaths()); - fatalErrorHappened = true; - } - else { - fatalError(getCommonErrorTitle(), result.getErrorOutputAsJoinedString()); - fatalErrorHappened = true; - } + } + finally { + GitUtil.workingTreeChangeFinished(myProject); } if (!fatalErrorHappened) { diff --git a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java index e90d1eb808ef..89a50cfd6054 100644 --- a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java +++ b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java @@ -72,76 +72,82 @@ class GitMergeOperation extends GitBranchOperation { saveAllDocuments(); boolean fatalErrorHappened = false; int alreadyUpToDateRepositories = 0; - while (hasMoreRepositories() && !fatalErrorHappened) { - final GitRepository repository = next(); - LOG.info("next repository: " + repository); - - VirtualFile root = repository.getRoot(); - GitLocalChangesWouldBeOverwrittenDetector localChangesDetector = - new GitLocalChangesWouldBeOverwrittenDetector(root, GitLocalChangesWouldBeOverwrittenDetector.Operation.MERGE); - GitSimpleEventDetector unmergedFiles = new GitSimpleEventDetector(GitSimpleEventDetector.Event.UNMERGED_PREVENTING_MERGE); - GitUntrackedFilesOverwrittenByOperationDetector untrackedOverwrittenByMerge = - new GitUntrackedFilesOverwrittenByOperationDetector(root); - GitSimpleEventDetector mergeConflict = new GitSimpleEventDetector(GitSimpleEventDetector.Event.MERGE_CONFLICT); - GitSimpleEventDetector alreadyUpToDateDetector = new GitSimpleEventDetector(GitSimpleEventDetector.Event.ALREADY_UP_TO_DATE); - - GitCommandResult result = myGit.merge(repository, myBranchToMerge, Collections.<String>emptyList(), - localChangesDetector, unmergedFiles, untrackedOverwrittenByMerge, mergeConflict, - alreadyUpToDateDetector); - if (result.success()) { - LOG.info("Merged successfully"); - refresh(repository); - markSuccessful(repository); - if (alreadyUpToDateDetector.hasHappened()) { - alreadyUpToDateRepositories += 1; + GitUtil.workingTreeChangeStarted(myProject); + try { + while (hasMoreRepositories() && !fatalErrorHappened) { + final GitRepository repository = next(); + LOG.info("next repository: " + repository); + + VirtualFile root = repository.getRoot(); + GitLocalChangesWouldBeOverwrittenDetector localChangesDetector = + new GitLocalChangesWouldBeOverwrittenDetector(root, GitLocalChangesWouldBeOverwrittenDetector.Operation.MERGE); + GitSimpleEventDetector unmergedFiles = new GitSimpleEventDetector(GitSimpleEventDetector.Event.UNMERGED_PREVENTING_MERGE); + GitUntrackedFilesOverwrittenByOperationDetector untrackedOverwrittenByMerge = + new GitUntrackedFilesOverwrittenByOperationDetector(root); + GitSimpleEventDetector mergeConflict = new GitSimpleEventDetector(GitSimpleEventDetector.Event.MERGE_CONFLICT); + GitSimpleEventDetector alreadyUpToDateDetector = new GitSimpleEventDetector(GitSimpleEventDetector.Event.ALREADY_UP_TO_DATE); + + GitCommandResult result = myGit.merge(repository, myBranchToMerge, Collections.<String>emptyList(), + localChangesDetector, unmergedFiles, untrackedOverwrittenByMerge, mergeConflict, + alreadyUpToDateDetector); + if (result.success()) { + LOG.info("Merged successfully"); + refresh(repository); + markSuccessful(repository); + if (alreadyUpToDateDetector.hasHappened()) { + alreadyUpToDateRepositories += 1; + } } - } - else if (unmergedFiles.hasHappened()) { - LOG.info("Unmerged files error!"); - fatalUnmergedFilesError(); - fatalErrorHappened = true; - } - else if (localChangesDetector.wasMessageDetected()) { - LOG.info("Local changes would be overwritten by merge!"); - boolean smartMergeSucceeded = proposeSmartMergePerformAndNotify(repository, localChangesDetector); - if (!smartMergeSucceeded) { + else if (unmergedFiles.hasHappened()) { + LOG.info("Unmerged files error!"); + fatalUnmergedFilesError(); + fatalErrorHappened = true; + } + else if (localChangesDetector.wasMessageDetected()) { + LOG.info("Local changes would be overwritten by merge!"); + boolean smartMergeSucceeded = proposeSmartMergePerformAndNotify(repository, localChangesDetector); + if (!smartMergeSucceeded) { + fatalErrorHappened = true; + } + } + else if (mergeConflict.hasHappened()) { + LOG.info("Merge conflict"); + myConflictedRepositories.put(repository, Boolean.FALSE); + refresh(repository); + markSuccessful(repository); + } + else if (untrackedOverwrittenByMerge.wasMessageDetected()) { + LOG.info("Untracked files would be overwritten by merge!"); + fatalUntrackedFilesError(repository.getRoot(), untrackedOverwrittenByMerge.getRelativeFilePaths()); + fatalErrorHappened = true; + } + else { + LOG.info("Unknown error. " + result); + fatalError(getCommonErrorTitle(), result.getErrorOutputAsJoinedString()); fatalErrorHappened = true; } } - else if (mergeConflict.hasHappened()) { - LOG.info("Merge conflict"); - myConflictedRepositories.put(repository, Boolean.FALSE); - refresh(repository); - markSuccessful(repository); - } - else if (untrackedOverwrittenByMerge.wasMessageDetected()) { - LOG.info("Untracked files would be overwritten by merge!"); - fatalUntrackedFilesError(repository.getRoot(), untrackedOverwrittenByMerge.getRelativeFilePaths()); - fatalErrorHappened = true; + + if (fatalErrorHappened) { + notifyAboutRemainingConflicts(); } else { - LOG.info("Unknown error. " + result); - fatalError(getCommonErrorTitle(), result.getErrorOutputAsJoinedString()); - fatalErrorHappened = true; + boolean allConflictsResolved = resolveConflicts(); + if (allConflictsResolved) { + if (alreadyUpToDateRepositories < getRepositories().size()) { + notifySuccess(); + } + else { + notifySuccess("Already up-to-date"); + } + } } - } - if (fatalErrorHappened) { - notifyAboutRemainingConflicts(); + restoreLocalChanges(); } - else { - boolean allConflictsResolved = resolveConflicts(); - if (allConflictsResolved) { - if (alreadyUpToDateRepositories < getRepositories().size()) { - notifySuccess(); - } - else { - notifySuccess("Already up-to-date"); - } - } + finally { + GitUtil.workingTreeChangeFinished(myProject); } - - restoreLocalChanges(); } private void notifyAboutRemainingConflicts() { diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java index 2eb0219485b6..3bb008a2f95f 100644 --- a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java +++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java @@ -601,8 +601,8 @@ public class GitCheckinEnvironment implements CheckinEnvironment { c.gridy = 0; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; - final List<String> usersList = getUsersList(project); - final Set<String> authors = new HashSet<String>(usersList); + + Set<String> authors = new HashSet<String>(getUsersList(project)); ContainerUtil.addAll(authors, mySettings.getCommitAuthors()); List<String> list = new ArrayList<String>(authors); Collections.sort(list); diff --git a/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java b/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java index 831f833e0db5..40865a0b3f13 100644 --- a/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java +++ b/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java @@ -21,37 +21,25 @@ import com.intellij.dvcs.ui.DvcsBundle; import com.intellij.openapi.project.Project; import git4idea.GitUtil; import git4idea.GitVcs; -import git4idea.commands.GitCommand; -import git4idea.commands.GitLineHandlerPasswordRequestAware; -import git4idea.commands.GitTask; -import git4idea.commands.GitTaskResult; +import git4idea.commands.*; import git4idea.remote.GitRememberedInputs; import org.jetbrains.annotations.NotNull; import java.io.File; -/** - * @author Nadya Zabrodina - */ public class GitCloneDialog extends CloneDvcsDialog { public GitCloneDialog(@NotNull Project project) { super(project, GitVcs.NAME, GitUtil.DOT_GIT); } - /* - * We have a hack here: if http response asked for a password, then the url is at least valid and existent, and we consider - * that the test passed. - */ protected boolean test(@NotNull String url) { - final GitLineHandlerPasswordRequestAware handler = - new GitLineHandlerPasswordRequestAware(myProject, new File("."), GitCommand.LS_REMOTE); + final GitLineHandler handler = new GitLineHandler(myProject, new File("."), GitCommand.LS_REMOTE); handler.setUrl(url); handler.addParameters(url, "master"); GitTask task = new GitTask(myProject, handler, DvcsBundle.message("clone.testing", url)); GitTaskResult result = task.executeModal(); - boolean authFailed = handler.hadAuthRequest(); - return result.isOK() || authFailed; + return result.isOK(); } @NotNull diff --git a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java index bd8635db89be..033b1fd106fc 100644 --- a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java +++ b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java @@ -33,6 +33,7 @@ import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.VcsFullCommitDetails; import git4idea.GitPlatformFacade; +import git4idea.GitUtil; import git4idea.commands.Git; import git4idea.commands.GitCommandResult; import git4idea.commands.GitSimpleEventDetector; @@ -80,15 +81,21 @@ public class GitCherryPicker { public void cherryPick(@NotNull Map<GitRepository, List<VcsFullCommitDetails>> commitsInRoots) { List<GitCommitWrapper> successfulCommits = new ArrayList<GitCommitWrapper>(); - for (Map.Entry<GitRepository, List<VcsFullCommitDetails>> entry : commitsInRoots.entrySet()) { - GitRepository repository = entry.getKey(); - boolean result = cherryPick(repository, entry.getValue(), successfulCommits); - repository.update(); - if (!result) { - return; + GitUtil.workingTreeChangeStarted(myProject); + try { + for (Map.Entry<GitRepository, List<VcsFullCommitDetails>> entry : commitsInRoots.entrySet()) { + GitRepository repository = entry.getKey(); + boolean result = cherryPick(repository, entry.getValue(), successfulCommits); + repository.update(); + if (!result) { + return; + } } + notifySuccess(successfulCommits); + } + finally { + GitUtil.workingTreeChangeFinished(myProject); } - notifySuccess(successfulCommits); } // return true to continue with other roots, false to break execution diff --git a/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java b/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java index 5b3a2422254f..e0312e5471fc 100644 --- a/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java +++ b/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java @@ -87,7 +87,7 @@ class GitHttpGuiAuthenticator implements GitHttpAuthenticator { return ""; } url = adjustUrl(url); - Pair<GitHttpAuthDataProvider, AuthData> authData = findBestAuthData(url); + Pair<GitHttpAuthDataProvider, AuthData> authData = findBestAuthData(url, myModalityState); if (authData != null && authData.second.getPassword() != null) { String password = authData.second.getPassword(); myDataProvider = authData.first; @@ -114,7 +114,7 @@ class GitHttpGuiAuthenticator implements GitHttpAuthenticator { @NotNull public String askUsername(@NotNull String url) { url = adjustUrl(url); - Pair<GitHttpAuthDataProvider, AuthData> authData = findBestAuthData(url); + Pair<GitHttpAuthDataProvider, AuthData> authData = findBestAuthData(url, myModalityState); String login = null; String password = null; if (authData != null) { @@ -223,10 +223,10 @@ class GitHttpGuiAuthenticator implements GitHttpAuthenticator { // return the first that knows username + password; otherwise return the first that knows just the username @Nullable - private Pair<GitHttpAuthDataProvider, AuthData> findBestAuthData(@NotNull String url) { + private Pair<GitHttpAuthDataProvider, AuthData> findBestAuthData(@NotNull String url, @Nullable ModalityState modalityState) { Pair<GitHttpAuthDataProvider, AuthData> candidate = null; for (GitHttpAuthDataProvider provider : getProviders()) { - AuthData data = provider.getAuthData(url); + AuthData data = provider.getAuthData(url, modalityState); if (data != null) { Pair<GitHttpAuthDataProvider, AuthData> pair = Pair.create(provider, data); if (data.getPassword() != null) { @@ -268,12 +268,12 @@ class GitHttpGuiAuthenticator implements GitHttpAuthenticator { @Nullable @Override - public AuthData getAuthData(@NotNull String url) { + public AuthData getAuthData(@NotNull String url, @Nullable ModalityState modalityState) { String userName = getUsername(url); String key = makeKey(url, userName); final PasswordSafe passwordSafe = PasswordSafe.getInstance(); try { - String password = passwordSafe.getPassword(myProject, PASS_REQUESTER, key); + String password = passwordSafe.getPassword(myProject, PASS_REQUESTER, key, modalityState); return new AuthData(StringUtil.notNullize(userName), password); } catch (PasswordSafeException e) { diff --git a/plugins/git4idea/src/git4idea/commands/GitImpl.java b/plugins/git4idea/src/git4idea/commands/GitImpl.java index 3e14a6414704..c873e71ff94b 100644 --- a/plugins/git4idea/src/git4idea/commands/GitImpl.java +++ b/plugins/git4idea/src/git4idea/commands/GitImpl.java @@ -138,7 +138,7 @@ public class GitImpl implements Git { return run(new Computable<GitLineHandler>() { @Override public GitLineHandler compute() { - GitLineHandlerPasswordRequestAware handler = new GitLineHandlerPasswordRequestAware(project, parentDirectory, GitCommand.CLONE); + GitLineHandler handler = new GitLineHandler(project, parentDirectory, GitCommand.CLONE); handler.setStdoutSuppressed(false); handler.setUrl(url); handler.addParameters("--progress"); @@ -376,8 +376,7 @@ public class GitImpl implements Git { return runCommand(new Computable<GitLineHandler>() { @Override public GitLineHandler compute() { - final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(repository.getProject(), repository.getRoot(), - GitCommand.PUSH); + final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.PUSH); h.setUrl(url); h.setSilent(false); h.setStdoutSuppressed(false); @@ -454,8 +453,7 @@ public class GitImpl implements Git { return runCommand(new Computable<GitLineHandler>() { @Override public GitLineHandler compute() { - final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(repository.getProject(), repository.getRoot(), - GitCommand.FETCH); + final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.FETCH); h.setUrl(url); h.addParameters(remote); h.addParameters(params); @@ -520,13 +518,7 @@ public class GitImpl implements Git { }); handler.runInCurrentThread(null); - authFailed = handler.hasHttpAuthFailed(); - - if (handler instanceof GitLineHandlerPasswordRequestAware && ((GitLineHandlerPasswordRequestAware)handler).hadAuthRequest()) { - errorOutput.add("Authentication failed"); - } - success = !startFailed.get() && errorOutput.isEmpty() && (handler.isIgnoredErrorCode(exitCode.get()) || exitCode.get() == 0); } while (authFailed && authAttempt++ < 2); diff --git a/plugins/git4idea/src/git4idea/commands/GitLineHandlerPasswordRequestAware.java b/plugins/git4idea/src/git4idea/commands/GitLineHandlerPasswordRequestAware.java deleted file mode 100644 index b117b2092946..000000000000 --- a/plugins/git4idea/src/git4idea/commands/GitLineHandlerPasswordRequestAware.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package git4idea.commands; - -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; - -import java.io.File; - -/** - * {@link GitLineHandler} that listens to Git output and kills itself if "username" or "password" is queried throughout the prompt. - * We can't pass the data to the prompt anyway, so better to kill the process and show an error message, than to hang the task. - * - * @author Kirill Likhodedov - */ -public class GitLineHandlerPasswordRequestAware extends GitLineHandler { - - private boolean myAuthRequest; - - public GitLineHandlerPasswordRequestAware(@NotNull Project project, @NotNull VirtualFile vcsRoot, @NotNull GitCommand command) { - super(project, vcsRoot, command); - } - - public GitLineHandlerPasswordRequestAware(@NotNull Project project, @NotNull File directory, @NotNull GitCommand clone) { - super(project, directory, clone); - } - - @Override - protected void onTextAvailable(String text, Key outputType) { - super.onTextAvailable(text, outputType); - if (text.toLowerCase().startsWith("password") || text.toLowerCase().startsWith("username")) { - myAuthRequest = true; - destroyProcess(); - } - } - - public boolean hadAuthRequest() { - return myAuthRequest; - } -} diff --git a/plugins/git4idea/src/git4idea/log/GitRefManager.java b/plugins/git4idea/src/git4idea/log/GitRefManager.java index 5b60076f68e7..eb9e79c69767 100644 --- a/plugins/git4idea/src/git4idea/log/GitRefManager.java +++ b/plugins/git4idea/src/git4idea/log/GitRefManager.java @@ -69,23 +69,31 @@ public class GitRefManager implements VcsLogRefManager { return typeComparison; } + //noinspection UnnecessaryLocalVariable VcsRefType type = type1; // common type + + String name1 = ref1.getName(); + String name2 = ref2.getName(); + if (name1.equals(name2)) { + return 0; + } + if (type == LOCAL_BRANCH) { - if (ref1.getName().equals(MASTER)) { + if (name1.equals(MASTER)) { return -1; } - if (ref2.getName().equals(MASTER)) { + if (name2.equals(MASTER)) { return 1; } - return ref1.getName().compareTo(ref2.getName()); + return name1.compareTo(name2); } if (type == REMOTE_BRANCH) { - if (ref1.getName().equals(ORIGIN_MASTER)) { + if (name1.equals(ORIGIN_MASTER)) { return -1; } - if (ref2.getName().equals(ORIGIN_MASTER)) { + if (name2.equals(ORIGIN_MASTER)) { return 1; } if (hasTrackingBranch(ref1) && !hasTrackingBranch(ref2)) { @@ -94,10 +102,10 @@ public class GitRefManager implements VcsLogRefManager { if (!hasTrackingBranch(ref1) && hasTrackingBranch(ref2)) { return 1; } - return ref1.getName().compareTo(ref2.getName()); + return name1.compareTo(name2); } - return ref1.getName().compareTo(ref2.getName()); + return name1.compareTo(name2); } }; @@ -121,10 +129,8 @@ public class GitRefManager implements VcsLogRefManager { @NotNull @Override - public List<VcsRef> sort(Collection<VcsRef> refs) { - ArrayList<VcsRef> list = new ArrayList<VcsRef>(refs); - Collections.sort(list, REF_COMPARATOR); - return list; + public Comparator<VcsRef> getComparator() { + return REF_COMPARATOR; } @NotNull @@ -314,7 +320,7 @@ public class GitRefManager implements VcsLogRefManager { @NotNull @Override public List<VcsRef> getRefs() { - return sort(myBranches); + return ContainerUtil.sorted(myBranches, getComparator()); } @NotNull diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java index a85a328fc114..aabf913fbf61 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java @@ -63,10 +63,6 @@ public class GitRebaser { mySkippedCommits = new ArrayList<GitRebaseUtils.CommitInfo>(); } - public void setProgressIndicator(@Nullable ProgressIndicator progressIndicator) { - myProgressIndicator = progressIndicator; - } - public GitUpdateResult rebase(@NotNull VirtualFile root, @NotNull List<String> parameters, @Nullable final Runnable onCancel, @@ -89,28 +85,34 @@ public class GitRebaser { rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer()); final AtomicReference<GitUpdateResult> updateResult = new AtomicReference<GitUpdateResult>(); final AtomicBoolean failure = new AtomicBoolean(); - rebaseTask.executeInBackground(true, new GitTaskResultHandlerAdapter() { - @Override - protected void onSuccess() { - updateResult.set(GitUpdateResult.SUCCESS); - } + try { + GitUtil.workingTreeChangeStarted(myProject); + rebaseTask.executeInBackground(true, new GitTaskResultHandlerAdapter() { + @Override + protected void onSuccess() { + updateResult.set(GitUpdateResult.SUCCESS); + } - @Override - protected void onCancel() { - if (onCancel != null) { - onCancel.run(); + @Override + protected void onCancel() { + if (onCancel != null) { + onCancel.run(); + } + updateResult.set(GitUpdateResult.CANCEL); } - updateResult.set(GitUpdateResult.CANCEL); - } - @Override - protected void onFailure() { - failure.set(true); - } - }); + @Override + protected void onFailure() { + failure.set(true); + } + }); - if (failure.get()) { - updateResult.set(handleRebaseFailure(root, rebaseHandler, rebaseConflictDetector, untrackedFilesDetector)); + if (failure.get()) { + updateResult.set(handleRebaseFailure(rebaseHandler, root, rebaseConflictDetector, untrackedFilesDetector)); + } + } + finally { + GitUtil.workingTreeChangeFinished(myProject); } return updateResult.get(); } @@ -119,26 +121,6 @@ public class GitRebaser { return new GitLineHandler(myProject, root, GitCommand.REBASE); } - public GitUpdateResult handleRebaseFailure(VirtualFile root, GitLineHandler pullHandler, - GitRebaseProblemDetector rebaseConflictDetector, - GitMessageWithFilesDetector untrackedWouldBeOverwrittenDetector) { - if (rebaseConflictDetector.isMergeConflict()) { - LOG.info("handleRebaseFailure merge conflict"); - final boolean allMerged = new MyConflictResolver(myProject, myGit, root, this).merge(); - return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE; - } else if (untrackedWouldBeOverwrittenDetector.wasMessageDetected()) { - LOG.info("handleRebaseFailure: untracked files would be overwritten by checkout"); - UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, root, - untrackedWouldBeOverwrittenDetector.getRelativeFilePaths(), "rebase", null); - return GitUpdateResult.ERROR; - } else { - LOG.info("handleRebaseFailure error " + pullHandler.errors()); - GitUIUtil.notifyImportantError(myProject, "Rebase error", GitUIUtil.stringifyErrors(pullHandler.errors())); - return GitUpdateResult.ERROR; - } - } - - public void abortRebase(@NotNull VirtualFile root) { LOG.info("abortRebase " + root); final GitLineHandler rh = new GitLineHandler(myProject, root, GitCommand.REBASE); @@ -158,11 +140,17 @@ public class GitRebaser { * @return true if rebase successfully finished. */ public boolean continueRebase(@NotNull Collection<VirtualFile> rebasingRoots) { - boolean success = true; - for (VirtualFile root : rebasingRoots) { - success &= continueRebase(root); + GitUtil.workingTreeChangeStarted(myProject); + try { + boolean success = true; + for (VirtualFile root : rebasingRoots) { + success &= continueRebase(root); + } + return success; + } + finally { + GitUtil.workingTreeChangeFinished(myProject); } - return success; } // start operation may be "--continue" or "--skip" depending on the situation. @@ -330,34 +318,6 @@ public class GitRebaser { "You also may <b>abort rebase</b> to restore the original branch and stop rebasing."); } - private static class MyConflictResolver extends GitConflictResolver { - private final GitRebaser myRebaser; - private final VirtualFile myRoot; - - public MyConflictResolver(Project project, @NotNull Git git, VirtualFile root, GitRebaser rebaser) { - super(project, git, ServiceManager.getService(GitPlatformFacade.class), Collections.singleton(root), makeParams()); - myRebaser = rebaser; - myRoot = root; - } - - private static Params makeParams() { - Params params = new Params(); - params.setReverse(true); - params.setMergeDescription("Merge conflicts detected. Resolve them before continuing rebase."); - params.setErrorNotificationTitle("Can't continue rebase"); - params.setErrorNotificationAdditionalDescription("Then you may <b>continue rebase</b>. <br/> You also may <b>abort rebase</b> to restore the original branch and stop rebasing."); - return params; - } - - @Override protected boolean proceedIfNothingToMerge() throws VcsException { - return myRebaser.continueRebase(myRoot); - } - - @Override protected boolean proceedAfterAllMerged() throws VcsException { - return myRebaser.continueRebase(myRoot); - } - } - public static class TrivialEditor extends GitInteractiveRebaseEditorHandler{ public TrivialEditor(@NotNull GitRebaseEditorService service, @NotNull Project project, diff --git a/plugins/git4idea/src/git4idea/remote/GitHttpAuthDataProvider.java b/plugins/git4idea/src/git4idea/remote/GitHttpAuthDataProvider.java index 6c0860ccf20a..281d69b772c3 100644 --- a/plugins/git4idea/src/git4idea/remote/GitHttpAuthDataProvider.java +++ b/plugins/git4idea/src/git4idea/remote/GitHttpAuthDataProvider.java @@ -15,6 +15,7 @@ */ package git4idea.remote; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.util.AuthData; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,7 @@ public interface GitHttpAuthDataProvider { ExtensionPointName<GitHttpAuthDataProvider> EP_NAME = ExtensionPointName.create("Git4Idea.GitHttpAuthDataProvider"); @Nullable - AuthData getAuthData(@NotNull String url); + AuthData getAuthData(@NotNull String url, @Nullable ModalityState modalityState); void forgetPassword(@NotNull String url); diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java index 5109d0600b69..576f326a8ea3 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java @@ -416,7 +416,7 @@ class GitRepositoryReader { LOG.info(".git/HEAD has not standard format: [" + headContent + "]. We've parsed branch [" + matcher.group(1) + "]"); return new Head(true, matcher.group(1)); } - throw new RepoStateException("Invalid format of the .git/HEAD file: \n" + headContent); + throw new RepoStateException("Invalid format of the .git/HEAD file: [" + headContent + "]"); } /** diff --git a/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java b/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java index 00f1830e6255..e255598e2046 100644 --- a/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java +++ b/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java @@ -141,15 +141,21 @@ public class GitRollbackEnvironment implements RollbackEnvironment { } } // revert files from HEAD - for (Map.Entry<VirtualFile, List<FilePath>> entry : toRevert.entrySet()) { - listener.accept(entry.getValue()); - try { - revert(entry.getKey(), entry.getValue()); - } - catch (VcsException e) { - exceptions.add(e); + GitUtil.workingTreeChangeStarted(myProject); + try { + for (Map.Entry<VirtualFile, List<FilePath>> entry : toRevert.entrySet()) { + listener.accept(entry.getValue()); + try { + revert(entry.getKey(), entry.getValue()); + } + catch (VcsException e) { + exceptions.add(e); + } } } + finally { + GitUtil.workingTreeChangeFinished(myProject); + } LocalFileSystem lfs = LocalFileSystem.getInstance(); HashSet<File> filesToRefresh = new HashSet<File>(); for (Change c : changes) { diff --git a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java index 3c8d7100c50c..9b13bb6cdb65 100644 --- a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java +++ b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java @@ -413,25 +413,31 @@ public class GitUnstashDialog extends DialogWrapper { GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(root); h.addLineListener(untrackedFilesDetector); - final Ref<GitCommandResult> result = Ref.create(); - ProgressManager.getInstance().run(new Task.Modal(h.project(), GitBundle.getString("unstash.unstashing"), false) { - public void run(@NotNull final ProgressIndicator indicator) { - h.addLineListener(new GitHandlerUtil.GitLineHandlerListenerProgress(indicator, h, "stash", false)); - Git git = ServiceManager.getService(Git.class); - result.set(git.runCommand(new Computable.PredefinedValueComputable<GitLineHandler>(h))); - } - }); + GitUtil.workingTreeChangeStarted(myProject); + try { + final Ref<GitCommandResult> result = Ref.create(); + ProgressManager.getInstance().run(new Task.Modal(h.project(), GitBundle.getString("unstash.unstashing"), false) { + public void run(@NotNull final ProgressIndicator indicator) { + h.addLineListener(new GitHandlerUtil.GitLineHandlerListenerProgress(indicator, h, "stash", false)); + Git git = ServiceManager.getService(Git.class); + result.set(git.runCommand(new Computable.PredefinedValueComputable<GitLineHandler>(h))); + } + }); - ServiceManager.getService(myProject, GitPlatformFacade.class).hardRefresh(root); - GitCommandResult res = result.get(); - if (conflict.get()) { - boolean conflictsResolved = new UnstashConflictResolver(myProject, root, getSelectedStash()).merge(); - LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved); - } else if (untrackedFilesDetector.wasMessageDetected()) { - UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, root, untrackedFilesDetector.getRelativeFilePaths(), - "unstash", null); - } else if (!res.success()) { - GitUIUtil.showOperationErrors(myProject, h.errors(), h.printableCommandLine()); + ServiceManager.getService(myProject, GitPlatformFacade.class).hardRefresh(root); + GitCommandResult res = result.get(); + if (conflict.get()) { + boolean conflictsResolved = new UnstashConflictResolver(myProject, root, getSelectedStash()).merge(); + LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved); + } else if (untrackedFilesDetector.wasMessageDetected()) { + UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, root, untrackedFilesDetector.getRelativeFilePaths(), + "unstash", null); + } else if (!res.success()) { + GitUIUtil.showOperationErrors(myProject, h.errors(), h.printableCommandLine()); + } + } + finally { + GitUtil.workingTreeChangeFinished(myProject); } super.doOKAction(); } diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index bc13ab8f7c36..e78039ef9d71 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java @@ -132,7 +132,13 @@ public class GitUpdateProcess { GitComplexProcess.Operation updateOperation = new GitComplexProcess.Operation() { @Override public void run(ContinuationContext continuationContext) { - myResult = updateImpl(updateMethod, continuationContext); + GitUtil.workingTreeChangeStarted(myProject); + try { + myResult = updateImpl(updateMethod, continuationContext); + } + finally { + GitUtil.workingTreeChangeFinished(myProject); + } } }; GitComplexProcess.execute(myProject, "update", updateOperation); |