@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(); }
/** * {@code git checkout <reference>} <br> * {@code git checkout -b <newBranch> <reference>} */ @NotNull @Override public GitCommandResult checkout( @NotNull GitRepository repository, @NotNull String reference, @Nullable String newBranch, boolean force, @NotNull GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECKOUT); h.setSilent(false); h.setStdoutSuppressed(false); if (force) { h.addParameters("--force"); } if (newBranch == null) { // simply checkout h.addParameters(reference); } else { // checkout reference as new branch h.addParameters("-b", newBranch, reference); } for (GitLineHandlerListener listener : listeners) { h.addLineListener(listener); } return run(h); }
@NotNull private static GitCommandResult run(@NotNull Computable<GitLineHandler> handlerConstructor) { final List<String> errorOutput = new ArrayList<String>(); final List<String> output = new ArrayList<String>(); final AtomicInteger exitCode = new AtomicInteger(); final AtomicBoolean startFailed = new AtomicBoolean(); final AtomicReference<Throwable> exception = new AtomicReference<Throwable>(); int authAttempt = 0; boolean authFailed; boolean success; do { errorOutput.clear(); output.clear(); exitCode.set(0); startFailed.set(false); exception.set(null); GitLineHandler handler = handlerConstructor.compute(); handler.addLineListener( new GitLineHandlerListener() { @Override public void onLineAvailable(String line, Key outputType) { if (isError(line)) { errorOutput.add(line); } else { output.add(line); } } @Override public void processTerminated(int code) { exitCode.set(code); } @Override public void startFailed(Throwable t) { startFailed.set(true); errorOutput.add("Failed to start Git process"); exception.set(t); } }); handler.runInCurrentThread(null); authFailed = handler.hasHttpAuthFailed(); success = !startFailed.get() && errorOutput.isEmpty() && (handler.isIgnoredErrorCode(exitCode.get()) || exitCode.get() == 0); } while (authFailed && authAttempt++ < 2); return new GitCommandResult(success, exitCode.get(), errorOutput, output, null); }
/** Calls 'git init' on the specified directory. */ @NotNull @Override public GitCommandResult init( @NotNull Project project, @NotNull VirtualFile root, @NotNull GitLineHandlerListener... listeners) { GitLineHandler h = new GitLineHandler(project, root, GitCommand.INIT); for (GitLineHandlerListener listener : listeners) { h.addLineListener(listener); } h.setSilent(false); return run(h); }
@Override @NotNull public GitCommandResult merge( @NotNull GitRepository repository, @NotNull String branchToMerge, @NotNull GitLineHandlerListener... listeners) { final GitLineHandler mergeHandler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.MERGE); mergeHandler.setSilent(false); mergeHandler.addParameters(branchToMerge); for (GitLineHandlerListener listener : listeners) { mergeHandler.addLineListener(listener); } return run(mergeHandler); }
/** {@code git branch -d <reference>} or {@code git branch -D <reference>} */ @NotNull @Override public GitCommandResult branchDelete( @NotNull GitRepository repository, @NotNull String branchName, boolean force, @NotNull GitLineHandlerListener... listeners) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); h.setSilent(false); h.addParameters(force ? "-D" : "-d"); h.addParameters(branchName); for (GitLineHandlerListener listener : listeners) { h.addLineListener(listener); } return run(h); }
/** * Runs the given {@link GitLineHandler} in the current thread and returns the {@link * GitCommandResult}. */ private static GitCommandResult run(@NotNull GitLineHandler handler, boolean remote) { handler.setNoSSH(!remote); final List<String> errorOutput = new ArrayList<String>(); final List<String> output = new ArrayList<String>(); final AtomicInteger exitCode = new AtomicInteger(); final AtomicBoolean startFailed = new AtomicBoolean(); handler.addLineListener( new GitLineHandlerListener() { @Override public void onLineAvailable(String line, Key outputType) { if (isError(line)) { errorOutput.add(line); } else { output.add(line); } } @Override public void processTerminated(int code) { exitCode.set(code); } @Override public void startFailed(Throwable exception) { startFailed.set(true); errorOutput.add("Failed to start Git process"); errorOutput.add(ExceptionUtil.getThrowableText(exception)); } }); handler.runInCurrentThread(null); if (handler instanceof GitLineHandlerPasswordRequestAware && ((GitLineHandlerPasswordRequestAware) handler).hadAuthRequest()) { errorOutput.add("Authentication failed"); } final boolean success = !startFailed.get() && errorOutput.isEmpty() && (handler.isIgnoredErrorCode(exitCode.get()) || exitCode.get() == 0); return new GitCommandResult(success, exitCode.get(), errorOutput, output); }
@NotNull @Override public GitCommandResult createNewTag( @NotNull GitRepository repository, @NotNull String tagName, @Nullable GitLineHandlerListener listener, @NotNull String reference) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.TAG); h.setSilent(false); h.addParameters(tagName); if (reference != null && !reference.isEmpty()) { h.addParameters(reference); } if (listener != null) { h.addLineListener(listener); } return run(h); }
/** {@code git checkout -b <branchName>} */ @NotNull @Override public GitCommandResult checkoutNewBranch( @NotNull GitRepository repository, @NotNull String branchName, @Nullable GitLineHandlerListener listener) { final GitLineHandler h = new GitLineHandler( repository.getProject(), repository.getRoot(), GitCommand.CHECKOUT.readLockingCommand()); h.setSilent(false); h.addParameters("-b"); h.addParameters(branchName); if (listener != null) { h.addLineListener(listener); } return run(h); }
private static void addListeners( @NotNull GitLineHandler handler, @NotNull GitLineHandlerListener... listeners) { for (GitLineHandlerListener listener : listeners) { handler.addLineListener(listener); } }
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(); }