@Override protected void doOKAction() { VirtualFile root = getGitRoot(); GitLineHandler h = handler(); final AtomicBoolean conflict = new AtomicBoolean(); h.addLineListener( new GitLineHandlerAdapter() { public void onLineAvailable(String line, Key outputType) { if (line.contains("Merge conflict")) { conflict.set(true); } } }); int rc = GitHandlerUtil.doSynchronously( h, GitBundle.getString("unstash.unstashing"), h.printableCommandLine(), false); root.refresh(true, true); if (conflict.get()) { boolean conflictsResolved = new UnstashConflictResolver(myProject, root, getSelectedStash()).merge(); LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved); } else if (rc != 0) { GitUIUtil.showOperationErrors(myProject, h.errors(), h.printableCommandLine()); } super.doOKAction(); }
private GitUpdateResult handleRebaseFailure( GitLineHandler pullHandler, GitRebaseProblemDetector rebaseConflictDetector, final GitMessageWithFilesDetector untrackedWouldBeOverwrittenDetector) { if (rebaseConflictDetector.isMergeConflict()) { LOG.info("handleRebaseFailure merge conflict"); final boolean allMerged = new MyConflictResolver(myProject, myGit, myRoot, myRebaser).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, ServiceManager.getService(myProject, GitPlatformFacade.class), untrackedWouldBeOverwrittenDetector.getFiles(), "rebase", null); return GitUpdateResult.ERROR; } else { LOG.info("handleRebaseFailure error " + pullHandler.errors()); GitUIUtil.notifyImportantError( myProject, "Rebase error", GitUIUtil.stringifyErrors(pullHandler.errors())); return GitUpdateResult.ERROR; } }
private boolean stash() { if (!mySyncResult.hasLocalRepository()) { LOG.error("unexpected null local repro in call to stash"); return false; } final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject); if (changeListManager.isFreezedWithNotification("Can not stash changes now")) return false; final GitLineHandler handler = new GitLineHandler(myProject, mySourceRepository.getRoot(), GitCommand.STASH); handler.addParameters("save"); handler.addParameters("--keep-index"); String date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(new Date()); myStashMessage = "Cloud Debugger saved changes from branch " + myOriginalBranchName + " at " + date; handler.addParameters(myStashMessage); AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { GitHandlerUtil.doSynchronously( handler, GitBundle.getString("stashing.title"), handler.printableCommandLine()); } finally { DvcsUtil.workingTreeChangeFinished(myProject, token); } return true; }
/** * Executes 'git push' for the given roots to push. Returns the list of errors if there were any. */ private List<VcsException> executePushCommand(final Collection<Root> rootsToPush) { final ArrayList<VcsException> errors = new ArrayList<VcsException>(); for (Root r : rootsToPush) { GitLineHandler h = new GitLineHandler(myProject, r.root, GitCommand.PUSH); String src = r.commitToPush != null ? r.commitToPush : r.currentBranch; h.addParameters("-v", r.remoteName, src + ":" + r.remoteBranch); GitPushUtils.trackPushRejectedAsError( h, "Rejected push (" + r.root.getPresentableUrl() + "): "); errors.addAll(GitHandlerUtil.doSynchronouslyWithExceptions(h)); } return errors; }
protected void fetch() throws ServerRuntimeException { final VirtualFile contentRoot = getContentRoot(); GitRepository repository = getRepository(); final GitLineHandler fetchHandler = new GitLineHandler(getProject(), contentRoot, GitCommand.FETCH); fetchHandler.setSilent(false); fetchHandler.addParameters(getRemoteName()); fetchHandler.addLineListener(createGitLineHandlerListener()); performRemoteGitTask(fetchHandler, CloudBundle.getText("fetching.application", getCloudName())); repository.update(); }
private static boolean createEmptyGitRepository( @NotNull Project project, @NotNull VirtualFile root, @NotNull ProgressIndicator indicator) { final GitLineHandler h = new GitLineHandler(project, root, GitCommand.INIT); GitHandlerUtil.runInCurrentThread( h, indicator, true, GitBundle.getString("initializing.title")); if (!h.errors().isEmpty()) { GitUIUtil.showOperationErrors(project, h.errors(), "git init"); LOG.info("Failed to create empty git repo: " + h.errors()); return false; } GitInit.refreshAndConfigureVcsMappings(project, root, root.getPath()); return true; }
/** @return unstash handler */ private GitLineHandler handler() { GitLineHandler h = new GitLineHandler(myProject, getGitRoot(), GitCommand.STASH); h.setNoSSH(true); String branch = myBranchTextField.getText(); if (branch.length() == 0) { h.addParameters(myPopStashCheckBox.isSelected() ? "pop" : "apply"); if (myReinstateIndexCheckBox.isSelected()) { h.addParameters("--index"); } } else { h.addParameters("branch", branch); } String selectedStash = getSelectedStash().getStash(); addStashParameter(h, selectedStash); return h; }
private static void takeLine( final Project project, String line, StringBuilder sb, GitLogParser parser, SymbolicRefsI refs, VirtualFile root, VcsException[] exc, GitLineHandler h, AsynchConsumer<GitCommit> gitCommitConsumer) { final String text = sb.toString(); sb.setLength(0); sb.append(line); if (text.length() == 0) return; GitLogRecord record = parser.parseOneRecord(text); final GitCommit gitCommit; try { gitCommit = createCommit(project, refs, root, record); } catch (VcsException e) { exc[0] = e; h.cancel(); return; } gitCommitConsumer.consume(gitCommit); }
private static void doRebaseCurrentBranch( @NotNull final Project project, @NotNull final VirtualFile root, @NotNull final ProgressIndicator indicator) { final GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project); final GitRebaser rebaser = new GitRebaser(project, ServiceManager.getService(Git.class), indicator); final GitLineHandler handler = new GitLineHandler(project, root, GitCommand.REBASE); handler.addParameters("upstream/master"); final GitRebaseProblemDetector rebaseConflictDetector = new GitRebaseProblemDetector(); handler.addLineListener(rebaseConflictDetector); final GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(root); handler.addLineListener(untrackedFilesDetector); GitTask pullTask = new GitTask(project, handler, "Rebasing from upstream/master"); pullTask.setProgressIndicator(indicator); pullTask.setProgressAnalyzer(new GitStandardProgressAnalyzer()); pullTask.execute( true, false, new GitTaskResultHandlerAdapter() { @Override protected void onSuccess() { root.refresh(false, true); repositoryManager.updateRepository(root); GithubNotifications.showInfo(project, "Success", "Successfully rebased GitHub fork"); } @Override protected void onFailure() { GitUpdateResult result = rebaser.handleRebaseFailure( handler, root, rebaseConflictDetector, untrackedFilesDetector); repositoryManager.updateRepository(root); if (result == GitUpdateResult.NOTHING_TO_UPDATE || result == GitUpdateResult.SUCCESS || result == GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS) { GithubNotifications.showInfo(project, "Success", "Successfully rebased GitHub fork"); } } }); }
public void doClone(File cloneDirParent, String cloneDirName, String gitUrl) throws ServerRuntimeException { final GitLineHandler handler = new GitLineHandler(getProject(), cloneDirParent, GitCommand.CLONE); handler.setSilent(false); handler.setUrl(gitUrl); handler.addParameters("--progress"); handler.addParameters(gitUrl); handler.addParameters(cloneDirName); handler.addParameters("-o"); handler.addParameters(getRemoteName()); handler.addLineListener(createGitLineHandlerListener()); performRemoteGitTask( handler, CloudBundle.getText("cloning.existing.application", getCloudName())); }
protected GitUpdateResult doUpdate() { LOG.info("doUpdate "); String remoteBranch = getRemoteBranchToMerge(); final GitLineHandler rebaseHandler = new GitLineHandler(myProject, myRoot, GitCommand.REBASE); rebaseHandler.addParameters(remoteBranch); final GitRebaseProblemDetector rebaseConflictDetector = new GitRebaseProblemDetector(); rebaseHandler.addLineListener(rebaseConflictDetector); GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(myRoot); rebaseHandler.addLineListener(untrackedFilesDetector); GitTask rebaseTask = new GitTask(myProject, rebaseHandler, "Rebasing"); rebaseTask.setProgressIndicator(myProgressIndicator); 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); } @Override protected void onCancel() { cancel(); updateResult.set(GitUpdateResult.CANCEL); } @Override protected void onFailure() { failure.set(true); } }); if (failure.get()) { updateResult.set( handleRebaseFailure(rebaseHandler, rebaseConflictDetector, untrackedFilesDetector)); } return updateResult.get(); }
private static GitLineHandler getLogHandler( Project project, VirtualFile root, GitLogParser parser, FilePath path, String lastCommit, String... parameters) { final GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG); h.setNoSSH(true); h.setStdoutSuppressed(true); h.addParameters("--name-status", parser.getPretty(), "--encoding=UTF-8", lastCommit); if (parameters != null && parameters.length > 0) { h.addParameters(parameters); } h.endOptions(); h.addRelativePaths(path); return h; }
public static void historyWithLinks( final Project project, FilePath path, @Nullable final SymbolicRefsI refs, @NotNull final AsynchConsumer<GitCommit> gitCommitConsumer, @Nullable final Getter<Boolean> isCanceled, @Nullable Collection<VirtualFile> paths, final String... parameters) throws VcsException { // adjust path using change manager path = getLastCommitName(project, path); final VirtualFile root = GitUtil.getGitRoot(path); final GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG); final GitLogParser parser = new GitLogParser( project, GitLogParser.NameStatus.STATUS, SHORT_HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, COMMITTER_EMAIL, SHORT_PARENTS, REF_NAMES, SUBJECT, BODY, RAW_BODY); h.setNoSSH(true); h.setStdoutSuppressed(true); h.addParameters(parameters); h.addParameters("--name-status", parser.getPretty(), "--encoding=UTF-8", "--full-history"); if (paths != null && !paths.isEmpty()) { h.endOptions(); h.addRelativeFiles(paths); } else { h.addParameters("--sparse"); h.endOptions(); h.addRelativePaths(path); } final VcsException[] exc = new VcsException[1]; final Semaphore semaphore = new Semaphore(); final StringBuilder sb = new StringBuilder(); final Ref<Boolean> skipFirst = new Ref<Boolean>(true); h.addLineListener( new GitLineHandlerAdapter() { @Override public void onLineAvailable(final String line, final Key outputType) { try { if (ProcessOutputTypes.STDOUT.equals(outputType)) { if (isCanceled != null && isCanceled.get()) { h.cancel(); return; } // if (line.charAt(line.length() - 1) != '\u0003') { if ((!line.startsWith("\u0001")) || skipFirst.get()) { if (sb.length() > 0) { sb.append("\n"); } sb.append(line); skipFirst.set(false); return; } takeLine(project, line, sb, parser, refs, root, exc, h, gitCommitConsumer); } } catch (ProcessCanceledException e) { h.cancel(); semaphore.up(); } } @Override public void processTerminated(int exitCode) { semaphore.up(); } @Override public void startFailed(Throwable exception) { semaphore.up(); } }); semaphore.down(); h.start(); semaphore.waitFor(); takeLine(project, "", sb, parser, refs, root, exc, h, gitCommitConsumer); gitCommitConsumer.finished(); if (exc[0] != null) { throw exc[0]; } }
public static void dumpFullHistory( final Project project, VirtualFile root, final String outFilePath) throws VcsException { if (!GitUtil.isGitRoot(new File(root.getPath()))) throw new VcsException("Path " + root.getPath() + " is not git repository root"); final GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG); // GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, COMMIT_TIME); h.setNoSSH(true); h.setSilent(true); h.addParameters( "--all", "--pretty=format:%H%x20%ct%x0A", "--date-order", "--reverse", "--encoding=UTF-8", "--full-history", "--sparse"); h.endOptions(); // for file sort final Long[] minTs = new Long[1]; minTs[0] = Long.MAX_VALUE; final Long[] maxTs = new Long[1]; minTs[0] = 0L; final OutputStream[] stream = new OutputStream[1]; try { stream[0] = new BufferedOutputStream(new FileOutputStream(outFilePath, false)); final Semaphore semaphore = new Semaphore(); final VcsException[] ioExceptions = new VcsException[1]; h.addLineListener( new GitLineHandlerListener() { @Override public void onLineAvailable(String line, Key outputType) { if (line.length() == 0) return; try { GitCommitsSequentialIndex.parseRecord(line); stream[0].write((line + '\n').getBytes("UTF-8")); } catch (IOException e) { ioExceptions[0] = new VcsException(e); h.cancel(); semaphore.up(); } catch (ProcessCanceledException e) { h.cancel(); semaphore.up(); } catch (VcsException e) { ioExceptions[0] = e; h.cancel(); semaphore.up(); } } @Override public void processTerminated(int exitCode) { semaphore.up(); } @Override public void startFailed(Throwable exception) { semaphore.up(); } }); semaphore.down(); h.start(); semaphore.waitFor(); if (ioExceptions[0] != null) { throw ioExceptions[0]; } } catch (FileNotFoundException e) { throw new VcsException(e); } finally { try { if (stream[0] != null) { stream[0].close(); } } catch (IOException e) { throw new VcsException(e); } } /*String result = h.run(); if (result.length() > 0) { throw new VcsException(result); }*/ File file = new File(outFilePath); if (!file.exists() || file.length() == 0) throw new VcsException("Short repository history not loaded"); }
public static void hashesWithParents( Project project, FilePath path, final AsynchConsumer<CommitHashPlusParents> consumer, final Getter<Boolean> isCanceled, Collection<VirtualFile> paths, final String... parameters) throws VcsException { // adjust path using change manager path = getLastCommitName(project, path); final VirtualFile root = GitUtil.getGitRoot(path); final GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG); final GitLogParser parser = new GitLogParser( project, GitLogParser.NameStatus.NAME, SHORT_HASH, COMMIT_TIME, SHORT_PARENTS, AUTHOR_NAME); h.setNoSSH(true); h.setStdoutSuppressed(true); h.addParameters(parameters); h.addParameters(parser.getPretty(), "--encoding=UTF-8", "--full-history"); if (paths != null && !paths.isEmpty()) { h.endOptions(); h.addRelativeFiles(paths); } else { h.addParameters("--sparse"); h.endOptions(); h.addRelativePaths(path); } final Semaphore semaphore = new Semaphore(); h.addLineListener( new GitLineHandlerListener() { @Override public void onLineAvailable(final String line, final Key outputType) { try { if (ProcessOutputTypes.STDOUT.equals(outputType)) { if (isCanceled != null && isCanceled.get()) { h.cancel(); return; } GitLogRecord record = parser.parseOneRecord(line); consumer.consume( new CommitHashPlusParents( record.getShortHash(), record.getParentsShortHashes(), record.getLongTimeStamp() * 1000, record.getAuthorName())); } } catch (ProcessCanceledException e) { h.cancel(); semaphore.up(); } } @Override public void processTerminated(int exitCode) { semaphore.up(); } @Override public void startFailed(Throwable exception) { semaphore.up(); } }); semaphore.down(); h.start(); semaphore.waitFor(); consumer.finished(); }
/** * Load VCS roots * * @param project the project * @param roots the VCS root list * @param exceptions the list of of exceptions to use * @param fetchData if true, the data for remote is fetched. * @return the loaded information about vcs roots */ private static List<Root> loadRoots( final Project project, final List<VirtualFile> roots, final Collection<VcsException> exceptions, final boolean fetchData) { final ArrayList<Root> rc = new ArrayList<Root>(); for (VirtualFile root : roots) { try { Root r = new Root(); rc.add(r); r.root = root; GitBranch b = GitBranch.current(project, root); if (b != null) { r.currentBranch = b.getFullName(); r.remoteName = b.getTrackedRemoteName(project, root); r.remoteBranch = b.getTrackedBranchName(project, root); if (r.remoteName != null) { if (fetchData && !r.remoteName.equals(".")) { GitLineHandler fetch = new GitLineHandler(project, root, GitCommand.FETCH); fetch.addParameters(r.remoteName, "-v"); Collection<VcsException> exs = GitHandlerUtil.doSynchronouslyWithExceptions(fetch); exceptions.addAll(exs); } GitBranch tracked = b.tracked(project, root); assert tracked != null : "Tracked branch cannot be null here"; final boolean trackedBranchExists = tracked.exists(root); if (!trackedBranchExists) { LOG.info("loadRoots tracked branch " + tracked + " doesn't exist yet"); } // check what remote commits are not yet merged if (trackedBranchExists) { GitSimpleHandler toPull = new GitSimpleHandler(project, root, GitCommand.LOG); toPull.addParameters( "--pretty=format:%H", r.currentBranch + ".." + tracked.getFullName()); toPull.setNoSSH(true); toPull.setStdoutSuppressed(true); StringScanner su = new StringScanner(toPull.run()); while (su.hasMoreData()) { if (su.line().trim().length() != 0) { r.remoteCommits++; } } } // check what local commits are to be pushed GitSimpleHandler toPush = new GitSimpleHandler(project, root, GitCommand.LOG); // if the tracked branch doesn't exist yet (nobody pushed the branch yet), show all // commits on this branch. final String revisions = trackedBranchExists ? tracked.getFullName() + ".." + r.currentBranch : r.currentBranch; toPush.addParameters("--pretty=format:%H%x20%ct%x20%at%x20%s%n%P", revisions); toPush.setNoSSH(true); toPush.setStdoutSuppressed(true); StringScanner sp = new StringScanner(toPush.run()); while (sp.hasMoreData()) { if (sp.isEol()) { sp.line(); continue; } Commit c = new Commit(); c.root = r; String hash = sp.spaceToken(); String time = sp.spaceToken(); c.revision = new GitRevisionNumber(hash, new Date(Long.parseLong(time) * 1000L)); c.authorTime = sp.spaceToken(); c.message = sp.line(); c.isMerge = sp.line().indexOf(' ') != -1; r.commits.add(c); } } } } catch (VcsException e) { exceptions.add(e); } } return rc; }