use of com.intellij.openapi.vcs.history.VcsRevisionNumber in project intellij-community by JetBrains.
the class GitHistoryUtils method history.
public static void history(@NotNull Project project, @NotNull FilePath path, @Nullable VirtualFile root, @NotNull VcsRevisionNumber startingRevision, @NotNull Consumer<GitFileRevision> consumer, @NotNull Consumer<VcsException> exceptionConsumer, String... parameters) {
// adjust path using change manager
final FilePath filePath = getLastCommitName(project, path);
final VirtualFile finalRoot;
try {
finalRoot = (root == null ? GitUtil.getGitRoot(filePath) : root);
} catch (VcsException e) {
exceptionConsumer.consume(e);
return;
}
final GitLogParser logParser = new GitLogParser(project, GitLogParser.NameStatus.STATUS, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_EMAIL, COMMITTER_NAME, COMMITTER_EMAIL, PARENTS, SUBJECT, BODY, RAW_BODY, AUTHOR_TIME);
final AtomicReference<String> firstCommit = new AtomicReference<>(startingRevision.asString());
final AtomicReference<String> firstCommitParent = new AtomicReference<>(firstCommit.get());
final AtomicReference<FilePath> currentPath = new AtomicReference<>(filePath);
final AtomicReference<GitLineHandler> logHandler = new AtomicReference<>();
final AtomicBoolean skipFurtherOutput = new AtomicBoolean();
final Consumer<GitLogRecord> resultAdapter = record -> {
if (skipFurtherOutput.get()) {
return;
}
if (record == null) {
exceptionConsumer.consume(new VcsException("revision details are null."));
return;
}
record.setUsedHandler(logHandler.get());
final GitRevisionNumber revision = new GitRevisionNumber(record.getHash(), record.getDate());
firstCommit.set(record.getHash());
final String[] parentHashes = record.getParentsHashes();
if (parentHashes.length < 1) {
firstCommitParent.set(null);
} else {
firstCommitParent.set(parentHashes[0]);
}
final String message = record.getFullMessage();
FilePath revisionPath;
try {
final List<FilePath> paths = record.getFilePaths(finalRoot);
if (paths.size() > 0) {
revisionPath = paths.get(0);
} else {
revisionPath = currentPath.get();
}
Couple<String> authorPair = Couple.of(record.getAuthorName(), record.getAuthorEmail());
Couple<String> committerPair = Couple.of(record.getCommitterName(), record.getCommitterEmail());
Collection<String> parents = Arrays.asList(parentHashes);
consumer.consume(new GitFileRevision(project, finalRoot, revisionPath, revision, Couple.of(authorPair, committerPair), message, null, new Date(record.getAuthorTimeStamp()), parents));
List<GitLogStatusInfo> statusInfos = record.getStatusInfos();
if (statusInfos.isEmpty()) {
return;
}
if (statusInfos.get(0).getType() == GitChangeType.ADDED && !filePath.isDirectory()) {
skipFurtherOutput.set(true);
}
} catch (VcsException e) {
exceptionConsumer.consume(e);
}
};
GitVcs vcs = GitVcs.getInstance(project);
GitVersion version = vcs != null ? vcs.getVersion() : GitVersion.NULL;
final AtomicBoolean criticalFailure = new AtomicBoolean();
while (currentPath.get() != null && firstCommitParent.get() != null) {
logHandler.set(getLogHandler(project, version, finalRoot, logParser, currentPath.get(), firstCommitParent.get(), parameters));
final MyTokenAccumulator accumulator = new MyTokenAccumulator(logParser);
final Semaphore semaphore = new Semaphore();
logHandler.get().addLineListener(new GitLineHandlerAdapter() {
@Override
public void onLineAvailable(String line, Key outputType) {
final GitLogRecord record = accumulator.acceptLine(line);
if (record != null) {
resultAdapter.consume(record);
}
}
@Override
public void startFailed(Throwable exception) {
//noinspection ThrowableInstanceNeverThrown
try {
exceptionConsumer.consume(new VcsException(exception));
} finally {
criticalFailure.set(true);
semaphore.up();
}
}
@Override
public void processTerminated(int exitCode) {
try {
super.processTerminated(exitCode);
final GitLogRecord record = accumulator.processLast();
if (record != null) {
resultAdapter.consume(record);
}
} catch (ProcessCanceledException ignored) {
} catch (Throwable t) {
LOG.error(t);
exceptionConsumer.consume(new VcsException("Internal error " + t.getMessage(), t));
criticalFailure.set(true);
} finally {
semaphore.up();
}
}
});
semaphore.down();
logHandler.get().start();
semaphore.waitFor();
if (criticalFailure.get()) {
return;
}
try {
Pair<String, FilePath> firstCommitParentAndPath = getFirstCommitParentAndPathIfRename(project, finalRoot, firstCommit.get(), currentPath.get(), version);
currentPath.set(firstCommitParentAndPath == null ? null : firstCommitParentAndPath.second);
firstCommitParent.set(firstCommitParentAndPath == null ? null : firstCommitParentAndPath.first);
skipFurtherOutput.set(false);
} catch (VcsException e) {
LOG.warn("Tried to get first commit rename path", e);
exceptionConsumer.consume(e);
return;
}
}
}
use of com.intellij.openapi.vcs.history.VcsRevisionNumber in project intellij-community by JetBrains.
the class GithubOpenCommitInBrowserFromAnnotateAction method getData.
@Nullable
@Override
protected CommitData getData(AnActionEvent e) {
if (myLineNumber < 0)
return null;
Project project = e.getData(CommonDataKeys.PROJECT);
VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
if (project == null || virtualFile == null)
return null;
Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
if (document == null)
return null;
GitRepository repository = GitUtil.getRepositoryManager(project).getRepositoryForFileQuick(virtualFile);
if (repository == null || !GithubUtil.isRepositoryOnGitHub(repository))
return null;
VcsRevisionNumber revisionNumber = myAnnotation.getLineRevisionNumber(myLineNumber);
return new CommitData(project, repository, revisionNumber != null ? revisionNumber.asString() : null);
}
use of com.intellij.openapi.vcs.history.VcsRevisionNumber in project intellij-community by JetBrains.
the class GitPreservingProcess method configureSaver.
/**
* Configures the saver: i.e. notifications and texts for the GitConflictResolver used inside.
*/
@NotNull
private GitChangesSaver configureSaver(@NotNull GitVcsSettings.UpdateChangesPolicy saveMethod) {
GitChangesSaver saver = GitChangesSaver.getSaver(myProject, myGit, myProgressIndicator, myStashMessage, saveMethod);
MergeDialogCustomizer mergeDialogCustomizer = new MergeDialogCustomizer() {
@Override
public String getMultipleFileMergeDescription(@NotNull Collection<VirtualFile> files) {
return String.format("<html>Uncommitted changes that were saved before %s have conflicts with files from <code>%s</code></html>", myOperationTitle, myDestinationName);
}
@Override
public String getLeftPanelTitle(@NotNull VirtualFile file) {
return "Uncommitted changes from stash";
}
@Override
public String getRightPanelTitle(@NotNull VirtualFile file, VcsRevisionNumber revisionNumber) {
return String.format("<html>Changes from <b><code>%s</code></b></html>", myDestinationName);
}
};
GitConflictResolver.Params params = new GitConflictResolver.Params().setReverse(true).setMergeDialogCustomizer(mergeDialogCustomizer).setErrorNotificationTitle("Local changes were not restored");
saver.setConflictResolverParams(params);
return saver;
}
Aggregations