@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();
  }
예제 #2
0
 /**
  * {@code git checkout &lt;reference&gt;} <br>
  * {@code git checkout -b &lt;newBranch&gt; &lt;reference&gt;}
  */
 @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);
 }
예제 #3
0
  @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 &lt;branchName&gt;} */
 @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();
  }