/** Show dialog for the project */ public static void showDialogForProject(final Project project) { GitVcs vcs = GitVcs.getInstance(project); List<VirtualFile> roots = GitRepositoryAction.getGitRoots(project, vcs); if (roots == null) { return; } List<VcsException> pushExceptions = new ArrayList<VcsException>(); showDialog(project, roots, pushExceptions); vcs.showErrors(pushExceptions, GitBundle.getString("push.active.action.name")); }
private boolean merge(boolean mergeDialogInvokedFromNotification) { try { final Collection<VirtualFile> initiallyUnmergedFiles = getUnmergedFiles(myRoots); if (initiallyUnmergedFiles.isEmpty()) { LOG.info("merge: no unmerged files"); return mergeDialogInvokedFromNotification ? true : proceedIfNothingToMerge(); } else { showMergeDialog(initiallyUnmergedFiles); final Collection<VirtualFile> unmergedFilesAfterResolve = getUnmergedFiles(myRoots); if (unmergedFilesAfterResolve.isEmpty()) { LOG.info("merge no more unmerged files"); return mergeDialogInvokedFromNotification ? true : proceedAfterAllMerged(); } else { LOG.info("mergeFiles unmerged files remain: " + unmergedFilesAfterResolve); if (mergeDialogInvokedFromNotification) { notifyUnresolvedRemainAfterNotification(); } else { notifyUnresolvedRemain(); } } } } catch (VcsException e) { if (myVcs.getExecutableValidator().checkExecutableAndNotifyIfNeeded()) { notifyException(e); } } return false; }
/** * Setup remotes combobox. The default remote for the current branch is selected by default. * * @param project the project * @param root the git root * @param currentBranch the current branch * @param remoteCombobox the combobox to update * @param fetchUrl if true, the fetch url is shown for remotes, push otherwise */ public static void setupRemotes( final Project project, final VirtualFile root, final String currentBranch, final JComboBox remoteCombobox, final boolean fetchUrl) { try { List<GitDeprecatedRemote> remotes = GitDeprecatedRemote.list(project, root); String remote = null; if (currentBranch != null) { remote = GitConfigUtil.getValue(project, root, "branch." + currentBranch + ".remote"); } remoteCombobox.setRenderer( getGitRemoteListCellRenderer(remote, fetchUrl, remoteCombobox.getRenderer())); GitDeprecatedRemote toSelect = null; remoteCombobox.removeAllItems(); for (GitDeprecatedRemote r : remotes) { remoteCombobox.addItem(r); if (r.name().equals(remote)) { toSelect = r; } } if (toSelect != null) { remoteCombobox.setSelectedItem(toSelect); } } catch (VcsException e) { GitVcs.getInstance(project) .showErrors(Collections.singletonList(e), GitBundle.getString("pull.retrieving.remotes")); } }
/** * The constructor * * @param project the context project */ public GitVcsPanel(@NotNull Project project) { myVcs = GitVcs.getInstance(project); myAppSettings = GitVcsApplicationSettings.getInstance(); myProjectSettings = GitVcsSettings.getInstance(project); myProject = project; mySSHExecutableComboBox.addItem(IDEA_SSH); mySSHExecutableComboBox.addItem(NATIVE_SSH); mySSHExecutableComboBox.setSelectedItem( GitVcsSettings.isDefaultIdeaSsh() ? IDEA_SSH : NATIVE_SSH); mySSHExecutableComboBox.setToolTipText( GitBundle.message( "git.vcs.config.ssh.mode.tooltip", ApplicationNamesInfo.getInstance().getFullProductName())); myTestButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { testConnection(); } }); myConvertTextFilesComboBox.addItem(CRLF_DO_NOT_CONVERT); myConvertTextFilesComboBox.addItem(CRLF_CONVERT_TO_PROJECT); myConvertTextFilesComboBox.addItem(CRLF_ASK); myConvertTextFilesComboBox.setSelectedItem(CRLF_ASK); myGitField.addBrowseFolderListener( GitBundle.getString("find.git.title"), GitBundle.getString("find.git.description"), project, new FileChooserDescriptor(true, false, false, false, false, false)); }
@Override public void directoryMappingChanged() { GitVcs vcs = GitVcs.getInstance(myProject); if (vcs == null) { return; } final VirtualFile[] roots = myVcsManager.getRootsUnderVcs(vcs); final Collection<VirtualFile> rootsToCheck = ContainerUtil.filter( roots, new Condition<VirtualFile>() { @Override public boolean value(VirtualFile root) { return getUser(root) == null; } }); if (!rootsToCheck.isEmpty()) { ApplicationManager.getApplication() .executeOnPooledThread( new Runnable() { public void run() { for (VirtualFile root : rootsToCheck) { getOrReadUser(root); } } }); } }
/** Adds {@code stash@{x}} parameter to the handler, quotes it if needed. */ private void addStashParameter(@NotNull GitHandler handler, @NotNull String stash) { if (GitVersionSpecialty.NEEDS_QUOTES_IN_STASH_NAME.existsIn(myVcs.getVersion())) { handler.addParameters("\"" + stash + "\""); handler.dontEscapeQuotes(); } else { handler.addParameters(stash); } }
/** * @param fetchAll Pass {@code true} to fetch all remotes and all branches (like {@code git fetch} * without parameters does). Pass {@code false} to fetch only the tracked branch of the * current branch. */ public GitFetcher( @NotNull Project project, @NotNull ProgressIndicator progressIndicator, boolean fetchAll) { myProject = project; myProgressIndicator = progressIndicator; myFetchAll = fetchAll; myRepositoryManager = GitUtil.getRepositoryManager(myProject); myVcs = GitVcs.getInstance(project); }
/** * Handles a low-level Git execution exception. Checks that Git executable is valid. If it is not, * then shows proper notification with an option to fix the path to Git. If it's valid, then we * don't know what could happen and just display the general error notification. */ public static void checkGitExecutableAndShowNotification(final Project project, VcsException e) { if (GitVcs.getInstance(project).getExecutableValidator().checkExecutableAndNotifyIfNeeded()) { GitVcs.IMPORTANT_ERROR_NOTIFICATION .createNotification( GitBundle.getString("general.error"), e.getLocalizedMessage(), NotificationType.ERROR, null) .notify(project); } }
public GitLogProvider( @NotNull Project project, @NotNull GitRepositoryManager repositoryManager, @NotNull VcsLogObjectsFactory factory, @NotNull GitUserRegistry userRegistry) { myProject = project; myRepositoryManager = repositoryManager; myUserRegistry = userRegistry; myRefSorter = new GitRefManager(myRepositoryManager); myVcsObjectsFactory = factory; myVcs = ObjectUtils.assertNotNull(GitVcs.getInstance(project)); }
private GitFetchResult fetchNatively( @NotNull VirtualFile root, @NotNull GitRemote remote, @Nullable String branch) { final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(myProject, root, GitCommand.FETCH); h.addProgressParameter(); if (GitVersionSpecialty.SUPPORTS_FETCH_PRUNE.existsIn(myVcs.getVersion())) { h.addParameters("--prune"); } String remoteName = remote.getName(); h.addParameters(remoteName); if (branch != null) { h.addParameters(getFetchSpecForBranch(branch, remoteName)); } final GitTask fetchTask = new GitTask(myProject, h, "Fetching " + remote.getFirstUrl()); fetchTask.setProgressIndicator(myProgressIndicator); fetchTask.setProgressAnalyzer(new GitStandardProgressAnalyzer()); GitFetchPruneDetector pruneDetector = new GitFetchPruneDetector(); h.addLineListener(pruneDetector); final AtomicReference<GitFetchResult> result = new AtomicReference<GitFetchResult>(); fetchTask.execute( true, false, new GitTaskResultHandlerAdapter() { @Override protected void onSuccess() { result.set(GitFetchResult.success()); } @Override protected void onCancel() { LOG.info("Cancelled fetch."); result.set(GitFetchResult.cancel()); } @Override protected void onFailure() { LOG.info("Error fetching: " + h.errors()); if (!h.hadAuthRequest()) { myErrors.addAll(h.errors()); } else { myErrors.add(new VcsException("Authentication failed")); } result.set(GitFetchResult.error(myErrors)); } }); result.get().addPruneInfo(pruneDetector.getPrunedRefs()); return result.get(); }
public static void displayFetchResult( @NotNull Project project, @NotNull GitFetchResult result, @Nullable String errorNotificationTitle, @NotNull Collection<? extends Exception> errors) { if (result.isSuccess()) { GitVcs.NOTIFICATION_GROUP_ID .createNotification( "Fetched successfully" + result.getAdditionalInfo(), NotificationType.INFORMATION) .notify(project); } else if (result.isCancelled()) { GitVcs.NOTIFICATION_GROUP_ID .createNotification( "Fetch cancelled by user" + result.getAdditionalInfo(), NotificationType.WARNING) .notify(project); } else if (result.isNotAuthorized()) { String title; String description; if (errorNotificationTitle != null) { title = errorNotificationTitle; description = "Fetch failed: couldn't authorize"; } else { title = "Fetch failed"; description = "Couldn't authorize"; } description += result.getAdditionalInfo(); GitUIUtil.notifyMessage(project, title, description, NotificationType.ERROR, true, null); } else { GitVcs instance = GitVcs.getInstance(project); if (instance != null && instance.getExecutableValidator().isExecutableValid()) { GitUIUtil.notifyMessage( project, "Fetch failed", result.getAdditionalInfo(), NotificationType.ERROR, true, errors); } } }
@NotNull @Override public List<? extends VcsFullCommitDetails> readFullDetails( @NotNull VirtualFile root, @NotNull List<String> hashes) throws VcsException { String noWalk = GitVersionSpecialty.NO_WALK_UNSORTED.existsIn(myVcs.getVersion()) ? "--no-walk=unsorted" : "--no-walk"; List<String> params = new ArrayList<String>(); params.add(noWalk); params.addAll(hashes); return GitHistoryUtils.history(myProject, root, ArrayUtil.toStringArray(params)); }
public GitConflictResolver( @NotNull Project project, @NotNull Git git, @NotNull Collection<VirtualFile> roots, @NotNull Params params) { myProject = project; myGit = git; myRoots = roots; myParams = params; myRepositoryManager = GitUtil.getRepositoryManager(myProject); myVcsHelper = AbstractVcsHelper.getInstance(project); myVcs = assertNotNull(GitVcs.getInstance(myProject)); }
@Before public void setUp() throws Throwable { IdeaTestApplication.getInstance(); myTestName = createTestName(); myProjectFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(myTestName).getFixture(); edt( new ThrowableRunnable<Exception>() { @Override public void run() throws Exception { myProjectFixture.setUp(); } }); myProject = myProjectFixture.getProject(); myProjectRoot = myProject.getBasePath(); myProjectDir = myProject.getBaseDir(); myTestRoot = myProjectRoot; myGit = ServiceManager.getService(myProject, Git.class); mySettings = GitVcsSettings.getInstance(myProject); mySettings.getAppSettings().setPathToGit(GitExecutor.PathHolder.GIT_EXECUTABLE); // dynamic overriding is used instead of making it in plugin.xml, // because MockVcsHelper is not ready to be a full featured implementation for all tests. myVcsHelper = GitTestUtil.overrideService(myProject, AbstractVcsHelper.class, MockVcsHelper.class); myChangeListManager = ChangeListManagerImpl.getInstanceImpl(myProject); myNotificator = (TestVcsNotifier) ServiceManager.getService(myProject, VcsNotifier.class); myVcs = GitVcs.getInstance(myProject); myRepositoryManager = GitUtil.getRepositoryManager(myProject); virtualCommits = new GitTestVirtualCommitsHolder(); myAsyncTasks = new ArrayList<>(); cd(myProjectRoot); myRepository = GitTestUtil.createRepository(myProject, myProjectRoot); ProjectLevelVcsManagerImpl vcsManager = (ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(myProject); AbstractVcs vcs = vcsManager.findVcsByName("Git"); Assert.assertEquals(1, vcsManager.getRootsUnderVcs(vcs).length); GitTestUtil.assumeSupportedGitVersion(myVcs); LOG.info(getStartTestMarker()); }
@Override public void actionPerformed(@NotNull AnActionEvent event) { final Project project = event.getProject(); if (project == null) { return; } final Set<VirtualFile> conflictedFiles = new TreeSet<VirtualFile>( new Comparator<VirtualFile>() { @Override public int compare(@NotNull VirtualFile f1, @NotNull VirtualFile f2) { return f1.getPresentableUrl().compareTo(f2.getPresentableUrl()); } }); for (Change change : ChangeListManager.getInstance(project).getAllChanges()) { if (change.getFileStatus() != FileStatus.MERGED_WITH_CONFLICTS) { continue; } final ContentRevision before = change.getBeforeRevision(); final ContentRevision after = change.getAfterRevision(); if (before != null) { final VirtualFile file = before.getFile().getVirtualFile(); if (file != null) { conflictedFiles.add(file); } } if (after != null) { final VirtualFile file = after.getFile().getVirtualFile(); if (file != null) { conflictedFiles.add(file); } } } AbstractVcsHelper.getInstance(project) .showMergeDialog( new ArrayList<VirtualFile>(conflictedFiles), GitVcs.getInstance(project).getMergeProvider()); for (VirtualFile conflictedFile : conflictedFiles) { final GitRepository repo = GitRepositoryManager.getInstance(project).getRepositoryForFile(conflictedFile); if (repo != null) { repo.update(GitRepository.TrackedTopic.ALL_CURRENT); } } }
protected GitUpdater( @NotNull Project project, @NotNull Git git, @NotNull VirtualFile root, @NotNull Map<VirtualFile, GitBranchPair> trackedBranches, @NotNull ProgressIndicator progressIndicator, @NotNull UpdatedFiles updatedFiles) { myProject = project; myGit = git; myRoot = root; myTrackedBranches = trackedBranches; myProgressIndicator = progressIndicator; myUpdatedFiles = updatedFiles; myVcsHelper = AbstractVcsHelper.getInstance(project); myVcs = GitVcs.getInstance(project); myRepositoryManager = GitUtil.getRepositoryManager(myProject); }
public synchronized byte[] getContent() throws IOException, VcsException { if (myNoCache) { return loadContent(); } return ContentRevisionCache.getOrLoadAsBytes( project, path, revision, GitVcs.getKey(), ContentRevisionCache.UniqueType.REPOSITORY_CONTENT, new Throwable2Computable<byte[], VcsException, IOException>() { @Override public byte[] compute() throws VcsException, IOException { return loadContent(); } }); }
/** * Save configuration panel state into settings object * * @param settings the settings object */ public void save(@NotNull GitVcsSettings settings) { settings.getAppSettings().setPathToGit(myGitField.getText()); myVcs.checkVersion(); settings.setIdeaSsh(IDEA_SSH.equals(mySSHExecutableComboBox.getSelectedItem())); Object policyItem = myConvertTextFilesComboBox.getSelectedItem(); GitVcsSettings.ConversionPolicy conversionPolicy; if (CRLF_DO_NOT_CONVERT.equals(policyItem)) { conversionPolicy = GitVcsSettings.ConversionPolicy.NONE; } else if (CRLF_CONVERT_TO_PROJECT.equals(policyItem)) { conversionPolicy = GitVcsSettings.ConversionPolicy.CONVERT; } else if (CRLF_ASK.equals(policyItem)) { conversionPolicy = GitVcsSettings.ConversionPolicy.ASK; } else { throw new IllegalStateException("Unknown selected CRLF policy: " + policyItem); } settings.setLineSeparatorsConversion(conversionPolicy); }
@Nullable @Override protected String getLastCommitMessage(@NotNull VirtualFile root) throws VcsException { GitSimpleHandler h = new GitSimpleHandler(myProject, root, GitCommand.LOG); h.addParameters("--max-count=1"); String formatPattern; if (GitVersionSpecialty.STARTED_USING_RAW_BODY_IN_FORMAT.existsIn(myVcs.getVersion())) { formatPattern = "%B"; } else { // only message: subject + body; "%-b" means that preceding line-feeds will be deleted if // the body is empty // %s strips newlines from subject; there is no way to work around it before 1.7.2 with %B // (unless parsing some fixed format) formatPattern = "%s%n%n%-b"; } h.addParameters("--pretty=format:" + formatPattern); return h.run(); }
GitCheckinOptions(@NotNull final Project project, @NotNull CheckinProjectPanel panel) { super(project, panel); myVcs = GitVcs.getInstance(project); final Insets insets = new Insets(2, 2, 2, 2); // add authors drop down GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.anchor = GridBagConstraints.WEST; c.insets = insets; final JLabel authorLabel = new JLabel(GitBundle.message("commit.author")); myPanel.add(authorLabel, c); c = new GridBagConstraints(); c.anchor = GridBagConstraints.CENTER; c.insets = insets; c.gridx = 1; c.gridy = 0; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; final List<String> usersList = getUsersList(project); final Set<String> authors = usersList == null ? new HashSet<String>() : new HashSet<String>(usersList); ContainerUtil.addAll(authors, mySettings.getCommitAuthors()); List<String> list = new ArrayList<String>(authors); Collections.sort(list); list = ObjectsConvertor.convert( list, new Convertor<String, String>() { @Override public String convert(String o) { return StringUtil.shortenTextWithEllipsis(o, 30, 0); } }); myAuthor = new ComboBox(ArrayUtil.toObjectArray(list)); myAuthor.insertItemAt("", 0); myAuthor.setSelectedItem(""); myAuthor.setEditable(true); authorLabel.setLabelFor(myAuthor); myAuthor.setToolTipText(GitBundle.getString("commit.author.tooltip")); myPanel.add(myAuthor, c); }
@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); }
private ReturnResult checkUserName() { Project project = myPanel.getProject(); GitVcs vcs = GitVcs.getInstance(project); assert vcs != null; Collection<VirtualFile> notDefined = new ArrayList<VirtualFile>(); Map<VirtualFile, Pair<String, String>> defined = new HashMap<VirtualFile, Pair<String, String>>(); Collection<VirtualFile> allRoots = new ArrayList<VirtualFile>( Arrays.asList(ProjectLevelVcsManager.getInstance(project).getRootsUnderVcs(vcs))); Collection<VirtualFile> affectedRoots = getSelectedRoots(); for (VirtualFile root : affectedRoots) { try { Pair<String, String> nameAndEmail = getUserNameAndEmailFromGitConfig(project, root); String name = nameAndEmail.getFirst(); String email = nameAndEmail.getSecond(); if (name == null || email == null) { notDefined.add(root); } else { defined.put(root, nameAndEmail); } } catch (VcsException e) { LOG.error("Couldn't get user.name and user.email for root " + root, e); // doing nothing - let commit with possibly empty user.name/email } } if (notDefined.isEmpty()) { return ReturnResult.COMMIT; } GitVersion version = vcs.getVersion(); if (System.getenv("HOME") == null && GitVersionSpecialty.DOESNT_DEFINE_HOME_ENV_VAR.existsIn(version)) { Messages.showErrorDialog( project, "You are using Git " + version + " which doesn't define %HOME% environment variable properly.\n" + "Consider updating Git to a newer version " + "or define %HOME% to point to the place where the global .gitconfig is stored \n" + "(it is usually %USERPROFILE% or %HOMEDRIVE%%HOMEPATH%).", "HOME Variable Is Not Defined"); return ReturnResult.CANCEL; } if (defined.isEmpty() && allRoots.size() > affectedRoots.size()) { allRoots.removeAll(affectedRoots); for (VirtualFile root : allRoots) { try { Pair<String, String> nameAndEmail = getUserNameAndEmailFromGitConfig(project, root); String name = nameAndEmail.getFirst(); String email = nameAndEmail.getSecond(); if (name != null && email != null) { defined.put(root, nameAndEmail); break; } } catch (VcsException e) { LOG.error("Couldn't get user.name and user.email for root " + root, e); // doing nothing - not critical not to find the values for other roots not affected by // commit } } } GitUserNameNotDefinedDialog dialog = new GitUserNameNotDefinedDialog(project, notDefined, affectedRoots, defined); dialog.show(); if (dialog.isOK()) { try { if (dialog.isGlobal()) { GitConfigUtil.setValue( project, notDefined.iterator().next(), GitConfigUtil.USER_NAME, dialog.getUserName(), "--global"); GitConfigUtil.setValue( project, notDefined.iterator().next(), GitConfigUtil.USER_EMAIL, dialog.getUserEmail(), "--global"); } else { for (VirtualFile root : notDefined) { GitConfigUtil.setValue(project, root, GitConfigUtil.USER_NAME, dialog.getUserName()); GitConfigUtil.setValue( project, root, GitConfigUtil.USER_EMAIL, dialog.getUserEmail()); } } } catch (VcsException e) { String message = "Couldn't set user.name and user.email"; LOG.error(message, e); Messages.showErrorDialog(myPanel.getComponent(), message); return ReturnResult.CANCEL; } return ReturnResult.COMMIT; } return ReturnResult.CLOSE_WINDOW; }
public GitCheckinHandlerFactory() { super(GitVcs.getKey()); }
/** * Constructs new dialog. Loads settings, registers listeners. * * @param project the project * @param vcsRoots the vcs roots * @param roots the loaded information about roots */ private GitPushActiveBranchesDialog( final Project project, List<VirtualFile> vcsRoots, List<Root> roots) { super(project, true); myVcs = GitVcs.getInstance(project); myProject = project; myVcsRoots = vcsRoots; myGeneralSettings = GeneralSettings.getInstance(); myProjectManager = ProjectManagerEx.getInstanceEx(); updateTree(roots, null); updateUI(); final GitVcsSettings settings = GitVcsSettings.getInstance(project); if (settings != null) { UpdatePolicyUtils.updatePolicyItem( settings.getPushActiveBranchesRebaseSavePolicy(), myStashRadioButton, myShelveRadioButton); } ChangeListener listener = new ChangeListener() { public void stateChanged(ChangeEvent e) { if (settings != null) { settings.setPushActiveBranchesRebaseSavePolicy( UpdatePolicyUtils.getUpdatePolicy(myStashRadioButton, myShelveRadioButton)); } } }; myStashRadioButton.addChangeListener(listener); myShelveRadioButton.addChangeListener(listener); myCommitTree .getSelectionModel() .addTreeSelectionListener( new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { TreePath path = myCommitTree.getSelectionModel().getSelectionPath(); if (path == null) { myViewButton.setEnabled(false); return; } DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); myViewButton.setEnabled( node != null && myCommitTree.getSelectionCount() == 1 && node.getUserObject() instanceof Commit); } }); myViewButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { TreePath path = myCommitTree.getSelectionModel().getSelectionPath(); if (path == null) { return; } DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); if (node == null || !(node.getUserObject() instanceof Commit)) { return; } Commit c = (Commit) node.getUserObject(); GitShowAllSubmittedFilesAction.showSubmittedFiles( project, c.revision.asString(), c.root.root); } }); myFetchButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { fetch(); } }); myRebaseButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { rebase(); } }); myPushButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { push(); } }); setTitle(GitBundle.getString("push.active.title")); setOKButtonText(GitBundle.getString("push.active.rebase.and.push")); setCancelButtonText(GitBundle.getString("git.push.active.close")); init(); }
/** * The most general execution method. * * @param sync Set to <code>true</code> to make the calling thread wait for the task execution. * @param modal If <code>true</code>, the task will be modal with a modal progress dialog. If * false, the task will be executed in background. <code>modal</code> implies <code>sync * </code>, i.e. if modal then sync doesn't matter: you'll wait anyway. * @param resultHandler Handle the result. * @see #execute(boolean) */ public void execute(boolean sync, boolean modal, final GitTaskResultHandler resultHandler) { final Object LOCK = new Object(); final AtomicBoolean completed = new AtomicBoolean(); if (modal) { final ModalTask task = new ModalTask(myProject, myHandler, myTitle) { @Override public void onSuccess() { commonOnSuccess(LOCK, resultHandler); completed.set(true); } @Override public void onCancel() { commonOnCancel(LOCK, resultHandler); completed.set(true); } }; GuiUtils.invokeAndWaitIfNeeded( new Runnable() { @Override public void run() { ProgressManager.getInstance().run(task); } }, ModalityState.defaultModalityState()); } else { final BackgroundableTask task = new BackgroundableTask(myProject, myHandler, myTitle) { @Override public void onSuccess() { commonOnSuccess(LOCK, resultHandler); completed.set(true); } @Override public void onCancel() { commonOnCancel(LOCK, resultHandler); completed.set(true); } }; if (myProgressIndicator == null) { GitVcs.runInBackground(task); } else { task.runAlone(); } } if (sync) { while (!completed.get()) { try { synchronized (LOCK) { LOCK.wait(50); } } catch (InterruptedException e) { LOG.info(e); } } } }
/** * This is called when "Rebase and Push" button (default button) is pressed. 1. Closes the dialog. * 2. Fetches project and rebases. 3. Repeats step 2 if needed - while current repository is * behind the parent one. 4. Then pushes. It may fail on one of these steps (especially on * rebasing with conflict) - then a notification error will be shown and the process will be * interrupted. */ private void rebaseAndPush() { final Task.Backgroundable rebaseAndPushTask = new Task.Backgroundable(myProject, GitBundle.getString("push.active.fetching")) { public void run(@NotNull ProgressIndicator indicator) { List<VcsException> exceptions = new ArrayList<VcsException>(); List<VcsException> pushExceptions = new ArrayList<VcsException>(); for (int i = 0; i < 3; i++) { RebaseInfo rebaseInfo = collectRebaseInfo(); if (rebaseInfo.reorderedCommits .isEmpty()) { // if we have to reorder commits, rebase must pre final Collection<Root> rootsToPush = getRootsToPush(); // collect roots from the dialog exceptions = executePushCommand(rootsToPush); if (exceptions.isEmpty() && !rootsToPush.isEmpty()) { // if nothing to push, execute rebase anyway int commitsNum = 0; for (Root root : rootsToPush) { commitsNum += root.commits.size(); Set<String> unchecked = rebaseInfo.uncheckedCommits.get(root.root); if (unchecked != null) { commitsNum -= unchecked.size(); } } final String pushMessage = "Pushed " + commitsNum + " " + StringUtil.pluralize("commit", commitsNum); VcsBalloonProblemNotifier.showOverVersionControlView( myVcs.getProject(), pushMessage, MessageType.INFO); for (Root root : rootsToPush) { GitRepositoryManager.getInstance(myProject) .updateRepository(root.root, GitRepository.TrackedTopic.ALL); } return; } pushExceptions = new ArrayList<VcsException>(exceptions); exceptions.clear(); } final List<Root> roots = loadRoots(myProject, myVcsRoots, exceptions, true); // fetch if (!exceptions.isEmpty()) { notifyMessage( myProject, "Failed to fetch", null, NotificationType.ERROR, true, exceptions); return; } updateTree(roots, rebaseInfo.uncheckedCommits); if (isRebaseNeeded()) { rebaseInfo = collectRebaseInfo(); executeRebase(exceptions, rebaseInfo); if (!exceptions.isEmpty()) { notifyMessage( myProject, "Failed to rebase", null, NotificationType.ERROR, true, exceptions); return; } VcsFileUtil.refreshFiles(myProject, rebaseInfo.roots); } } notifyMessage( myProject, "Failed to push", "Update project and push again", NotificationType.ERROR, true, pushExceptions); } }; GitVcs.runInBackground(rebaseAndPushTask); }
@NotNull @Override public VcsKey getSupportedVcs() { return GitVcs.getKey(); }
boolean isValid() { return project != null && log != null && DvcsUtil.logHasRootForVcs(log, GitVcs.getKey()); }
public static void assumeSupportedGitVersion(@NotNull GitVcs vcs) { GitVersion version = vcs.getVersion(); assumeTrue("Unsupported Git version: " + version, version.isSupported()); }
/** * A constructor * * @param project the project * @param roots the list of the roots * @param defaultRoot the default root to select */ public GitUnstashDialog( final Project project, final List<VirtualFile> roots, final VirtualFile defaultRoot) { super(project, true); setModal(false); myProject = project; myVcs = GitVcs.getInstance(project); setTitle(GitBundle.getString("unstash.title")); setOKButtonText(GitBundle.getString("unstash.button.apply")); GitUIUtil.setupRootChooser(project, roots, defaultRoot, myGitRootComboBox, myCurrentBranch); myStashList.setModel(new DefaultListModel()); refreshStashList(); myGitRootComboBox.addActionListener( new ActionListener() { public void actionPerformed(final ActionEvent e) { refreshStashList(); updateDialogState(); } }); myStashList.addListSelectionListener( new ListSelectionListener() { public void valueChanged(final ListSelectionEvent e) { updateDialogState(); } }); myBranchTextField .getDocument() .addDocumentListener( new DocumentAdapter() { protected void textChanged(final DocumentEvent e) { updateDialogState(); } }); myPopStashCheckBox.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { updateDialogState(); } }); myClearButton.addActionListener( new ActionListener() { public void actionPerformed(final ActionEvent e) { if (Messages.YES == Messages.showYesNoDialog( GitUnstashDialog.this.getContentPane(), GitBundle.message("git.unstash.clear.confirmation.message"), GitBundle.message("git.unstash.clear.confirmation.title"), Messages.getWarningIcon())) { GitLineHandler h = new GitLineHandler(myProject, getGitRoot(), GitCommand.STASH); h.setNoSSH(true); h.addParameters("clear"); GitHandlerUtil.doSynchronously( h, GitBundle.getString("unstash.clearing.stashes"), h.printableCommandLine()); refreshStashList(); updateDialogState(); } } }); myDropButton.addActionListener( new ActionListener() { public void actionPerformed(final ActionEvent e) { final StashInfo stash = getSelectedStash(); if (Messages.YES == Messages.showYesNoDialog( GitUnstashDialog.this.getContentPane(), GitBundle.message( "git.unstash.drop.confirmation.message", stash.getStash(), stash.getMessage()), GitBundle.message("git.unstash.drop.confirmation.title", stash.getStash()), Messages.getQuestionIcon())) { final ModalityState current = ModalityState.current(); ProgressManager.getInstance() .run( new Task.Modal(myProject, "Removing stash " + stash.getStash(), false) { @Override public void run(@NotNull ProgressIndicator indicator) { final GitSimpleHandler h = dropHandler(stash.getStash()); try { h.run(); h.unsilence(); } catch (final VcsException ex) { ApplicationManager.getApplication() .invokeLater( new Runnable() { @Override public void run() { GitUIUtil.showOperationError( myProject, ex, h.printableCommandLine()); } }, current); } } }); refreshStashList(); updateDialogState(); } } private GitSimpleHandler dropHandler(String stash) { GitSimpleHandler h = new GitSimpleHandler(myProject, getGitRoot(), GitCommand.STASH); h.setNoSSH(true); h.addParameters("drop"); addStashParameter(h, stash); return h; } }); myViewButton.addActionListener( new ActionListener() { public void actionPerformed(final ActionEvent e) { final VirtualFile root = getGitRoot(); String resolvedStash; String selectedStash = getSelectedStash().getStash(); try { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.REV_LIST); h.setNoSSH(true); h.setSilent(true); h.addParameters("--timestamp", "--max-count=1"); addStashParameter(h, selectedStash); h.endOptions(); final String output = h.run(); resolvedStash = GitRevisionNumber.parseRevlistOutputAsRevisionNumber(h, output).asString(); } catch (VcsException ex) { GitUIUtil.showOperationError(myProject, ex, "resolving revision"); return; } GitShowAllSubmittedFilesAction.showSubmittedFiles( myProject, resolvedStash, root, true, false); } }); init(); updateDialogState(); }