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; } }
@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(); }
@Override @NotNull public GitCommandResult resetHard(@NotNull GitRepository repository, @NotNull String revision) { final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.RESET); handler.addParameters("--hard", revision); return run(handler); }
@NotNull @Override public GitCommandResult show(@NotNull GitRepository repository, @NotNull String... params) { final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.SHOW); handler.addParameters(params); return run(handler); }
@NotNull @Override public GitCommandResult config(@NotNull GitRepository repository, String... params) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CONFIG); h.addParameters(params); return run(h); }
/** * Returns the last (tip) commit on the given branch.<br> * {@code git rev-list -1 <branchName>} */ @NotNull @Override public GitCommandResult tip(@NotNull GitRepository repository, @NotNull String branchName) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REV_LIST); h.addParameters("-1"); h.addParameters(branchName); return run(h); }
/** Get branches containing the commit. {@code git branch --contains <commit>} */ @Override @NotNull public GitCommandResult branchContains( @NotNull GitRepository repository, @NotNull String commit) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); h.addParameters("--contains", commit); return run(h); }
@NotNull @Override public GitCommandResult getUnmergedFiles(@NotNull GitRepository repository) { GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.LS_FILES); h.addParameters("--unmerged"); h.setSilent(true); return run(h); }
@NotNull @Override public GitCommandResult stashSave(@NotNull GitRepository repository, @NotNull String message) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.STASH); h.addParameters("save"); h.addParameters(message); return run(h); }
/** Create branch without checking it out. {@code git branch <branchName>} */ @Override @NotNull public GitCommandResult branchCreate( @NotNull GitRepository repository, @NotNull String branchName) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); h.addParameters(branchName); return run(h); }
@NotNull @Override public GitCommandResult stashPop( @NotNull GitRepository repository, @NotNull GitLineHandlerListener... listeners) { final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.STASH); handler.addParameters("pop"); addListeners(handler, listeners); return run(handler); }
@Override @NotNull public GitCommandResult resetMerge(@NotNull GitRepository repository, @Nullable String revision) { final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.RESET); handler.addParameters("--merge"); if (revision != null) { handler.addParameters(revision); } return run(handler); }
/** * 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(); }
@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); }
@NotNull @Override public GitCommandResult checkAttr( @NotNull GitRepository repository, @NotNull Collection<String> attributes, @NotNull Collection<VirtualFile> files) { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECK_ATTR); h.addParameters(new ArrayList<String>(attributes)); h.endOptions(); h.addRelativeFiles(files); return run(h); }
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; }
/** 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); }
/** @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"); } } }); }
/** {@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); }
/** * {@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); }
@Override @NotNull public GitCommandResult cherryPick( @NotNull GitRepository repository, @NotNull String hash, boolean autoCommit, @NotNull GitLineHandlerListener... listeners) { final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHERRY_PICK); handler.addParameters("-x"); if (!autoCommit) { handler.addParameters("-n"); } handler.addParameters(hash); addListeners(handler, listeners); handler.setSilent(false); return run(handler); }
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(); }
@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); }