Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions plugin/src/main/java/git4idea/actions/GitAdd.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,22 @@
*/
package git4idea.actions;

import consulo.annotation.component.ActionImpl;
import consulo.annotation.component.ActionRef;
import consulo.ide.impl.idea.openapi.vcs.changes.actions.ScheduleForAdditionAction;
import consulo.localize.LocalizeValue;
import consulo.platform.base.icon.PlatformIconGroup;
import consulo.ui.ex.action.AnActionEvent;
import consulo.virtualFileSystem.status.FileStatus;

import jakarta.annotation.Nonnull;

@ActionImpl(id = "Git.Add", shortcutFrom = @ActionRef(id = "ChangesView.AddUnversioned"))
public class GitAdd extends ScheduleForAdditionAction {
public GitAdd() {
super(LocalizeValue.localizeTODO("Add"), LocalizeValue.localizeTODO("Add"), PlatformIconGroup.generalAdd());
}

@Override
protected boolean isStatusForAddition(FileStatus status) {
return status == FileStatus.UNKNOWN
Expand Down
339 changes: 181 additions & 158 deletions plugin/src/main/java/git4idea/history/GitHistoryProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@
import consulo.annotation.component.ComponentScope;
import consulo.annotation.component.ServiceAPI;
import consulo.annotation.component.ServiceImpl;
import consulo.ide.impl.idea.openapi.vcs.annotate.ShowAllAffectedGenericAction;
import consulo.ide.impl.idea.openapi.vcs.history.CopyRevisionNumberAction;
import consulo.logging.Logger;
import consulo.project.Project;
import consulo.ui.ex.action.ActionManager;
import consulo.ui.ex.action.AnAction;
import consulo.ui.ex.awt.ColumnInfo;
import consulo.util.collection.ArrayUtil;
import consulo.util.lang.StringUtil;
import consulo.versionControlSystem.FilePath;
import consulo.versionControlSystem.VcsConfiguration;
import consulo.versionControlSystem.VcsException;
import consulo.versionControlSystem.action.VcsActions;
import consulo.versionControlSystem.action.VcsContextFactory;
import consulo.versionControlSystem.change.ContentRevision;
import consulo.versionControlSystem.history.*;
Expand All @@ -46,6 +47,7 @@

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;

import javax.swing.*;
import java.util.Collections;
import java.util.List;
Expand All @@ -57,167 +59,188 @@
@Singleton
@ServiceAPI(ComponentScope.PROJECT)
@ServiceImpl
public class GitHistoryProvider implements VcsHistoryProvider, VcsCacheableHistorySessionFactory<Boolean, VcsAbstractHistorySession>, VcsBaseRevisionAdviser {
private static final Logger log = Logger.getInstance(GitHistoryProvider.class.getName());

@Nonnull
private final Project myProject;

@Inject
public GitHistoryProvider(@Nonnull Project project) {
myProject = project;
}

public VcsDependentHistoryComponents getUICustomization(final VcsHistorySession session,
JComponent forShortcutRegistration) {
return VcsDependentHistoryComponents.createOnlyColumns(new ColumnInfo[0]);
}

public AnAction[] getAdditionalActions(Runnable refresher) {
return new AnAction[]{
ShowAllAffectedGenericAction.getInstance(),
new CopyRevisionNumberAction()
};
}

public boolean isDateOmittable() {
return false;
}

@Nullable
public String getHelpId() {
return null;
}

@Override
public FilePath getUsedFilePath(VcsAbstractHistorySession session) {
return null;
}

@Override
public Boolean getAddinionallyCachedData(VcsAbstractHistorySession session) {
return null;
}

@Override
public VcsAbstractHistorySession createFromCachedData(Boolean aBoolean,
@Nonnull List<VcsFileRevision> revisions,
@Nonnull FilePath filePath,
VcsRevisionNumber currentRevision) {
return createSession(filePath, revisions, currentRevision);
}

@Nullable
public VcsHistorySession createSessionFor(final FilePath filePath) throws VcsException {
List<VcsFileRevision> revisions = null;
try {
revisions = GitHistoryUtils.history(myProject, filePath);
}
catch (VcsException e) {
GitVcs.getInstance(myProject).getExecutableValidator().showNotificationOrThrow(e);
}
return createSession(filePath, revisions, null);
}

private VcsAbstractHistorySession createSession(final FilePath filePath, final List<VcsFileRevision> revisions,
@Nullable final VcsRevisionNumber number) {
return new VcsAbstractHistorySession(revisions, number) {
@Nullable
protected VcsRevisionNumber calcCurrentRevisionNumber() {
public class GitHistoryProvider
implements VcsHistoryProvider, VcsCacheableHistorySessionFactory<Boolean, VcsAbstractHistorySession>, VcsBaseRevisionAdviser {
private static final Logger log = Logger.getInstance(GitHistoryProvider.class);

@Nonnull
private final Project myProject;

@Inject
public GitHistoryProvider(@Nonnull Project project) {
myProject = project;
}

@Override
public VcsDependentHistoryComponents getUICustomization(
final VcsHistorySession session,
JComponent forShortcutRegistration
) {
return VcsDependentHistoryComponents.createOnlyColumns(new ColumnInfo[0]);
}

@Override
public AnAction[] getAdditionalActions(Runnable refresher) {
return new AnAction[]{
ActionManager.getInstance().getAction(VcsActions.ACTION_SHOW_ALL_AFFECTED),
new CopyRevisionNumberAction()
};
}

@Override
public boolean isDateOmittable() {
return false;
}

@Nullable
@Override
public String getHelpId() {
return null;
}

@Override
public FilePath getUsedFilePath(VcsAbstractHistorySession session) {
return null;
}

@Override
public Boolean getAddinionallyCachedData(VcsAbstractHistorySession session) {
return null;
}

@Override
public VcsAbstractHistorySession createFromCachedData(
Boolean aBoolean,
@Nonnull List<VcsFileRevision> revisions,
@Nonnull FilePath filePath,
VcsRevisionNumber currentRevision
) {
return createSession(filePath, revisions, currentRevision);
}

@Nullable
@Override
public VcsHistorySession createSessionFor(final FilePath filePath) throws VcsException {
List<VcsFileRevision> revisions = null;
try {
return GitHistoryUtils.getCurrentRevision(myProject, filePath, "HEAD");
revisions = GitHistoryUtils.history(myProject, filePath);
}
catch (VcsException e) {
// likely the file is not under VCS anymore.
if (log.isDebugEnabled()) {
log.debug("Unable to retrieve the current revision number", e);
}
return null;
GitVcs.getInstance(myProject).getExecutableValidator().showNotificationOrThrow(e);
}
}
return createSession(filePath, revisions, null);
}

public HistoryAsTreeProvider getHistoryAsTreeProvider() {
return null;
}

@Override
public VcsHistorySession copy() {
return createSession(filePath, getRevisionList(), getCurrentRevisionNumber());
}
};
}

@Override
public boolean getBaseVersionContent(FilePath filePath,
Predicate<CharSequence> processor,
final String beforeVersionId,
List<String> warnings)
throws VcsException {
if (StringUtil.isEmptyOrSpaces(beforeVersionId) || filePath.getVirtualFile() == null) {
return false;
}
// apply if base revision id matches revision
final VirtualFile root = GitUtil.getGitRoot(filePath);
if (root == null) {
return false;
}

final SHAHash shaHash = GitChangeUtils.commitExists(myProject, root, beforeVersionId, null, "HEAD");
if (shaHash == null) {
throw new VcsException("Can not apply patch to " + filePath.getPath() + ".\nCan not find revision '" + beforeVersionId + "'.");
}

final ContentRevision content = GitVcs.getInstance(myProject).getDiffProvider()
.createFileContent(new GitRevisionNumber(shaHash.getValue()), filePath.getVirtualFile());
if (content == null) {
throw new VcsException("Can not load content of '" + filePath.getPath() + "' for revision '" + shaHash.getValue() + "'");
}
return !processor.test(content.getContent());
}

public void reportAppendableHistory(final FilePath path, final VcsAppendableHistorySessionPartner partner) throws VcsException {
final VcsAbstractHistorySession emptySession = createSession(path, Collections.<VcsFileRevision>emptyList(), null);
partner.reportCreatedEmptySession(emptySession);

VcsConfiguration vcsConfiguration = VcsConfiguration.getInstance(myProject);
String[] additionalArgs = vcsConfiguration.LIMIT_HISTORY ?
new String[]{"--max-count=" + vcsConfiguration.MAXIMUM_HISTORY_ROWS} :
ArrayUtil.EMPTY_STRING_ARRAY;

final GitExecutableValidator validator = GitVcs.getInstance(myProject).getExecutableValidator();
GitHistoryUtils.history(myProject, refreshPath(path), null, gitFileRevision -> partner.acceptRevision(gitFileRevision), e -> {
if (validator.checkExecutableAndNotifyIfNeeded()) {
partner.reportException(e);
}
}, additionalArgs);
}

/**
* Refreshes the IO File inside this FilePath to let it survive moves.
*/
@Nonnull
private static FilePath refreshPath(@Nonnull FilePath path) {
VirtualFile virtualFile = path.getVirtualFile();
if (virtualFile == null) {
return path;
}
return VcsContextFactory.getInstance().createFilePathOn(virtualFile);
}

public boolean supportsHistoryForDirectories() {
return true;
}

@Override
public DiffFromHistoryHandler getHistoryDiffHandler() {
return new GitDiffFromHistoryHandler(myProject);
}

@Override
public boolean canShowHistoryFor(@Nonnull VirtualFile file) {
GitRepositoryManager manager = GitUtil.getRepositoryManager(myProject);
GitRepository repository = manager.getRepositoryForFile(file);
return repository != null && !repository.isFresh();
}
private VcsAbstractHistorySession createSession(
final FilePath filePath, final List<VcsFileRevision> revisions,
@Nullable final VcsRevisionNumber number
) {
return new VcsAbstractHistorySession(revisions, number) {
@Nullable
@Override
protected VcsRevisionNumber calcCurrentRevisionNumber() {
try {
return GitHistoryUtils.getCurrentRevision(myProject, filePath, "HEAD");
}
catch (VcsException e) {
// likely the file is not under VCS anymore.
if (log.isDebugEnabled()) {
log.debug("Unable to retrieve the current revision number", e);
}
return null;
}
}

@Override
public HistoryAsTreeProvider getHistoryAsTreeProvider() {
return null;
}

@Override
public VcsHistorySession copy() {
return createSession(filePath, getRevisionList(), getCurrentRevisionNumber());
}
};
}

@Override
public boolean getBaseVersionContent(
FilePath filePath,
Predicate<CharSequence> processor,
final String beforeVersionId,
List<String> warnings
)
throws VcsException {
if (StringUtil.isEmptyOrSpaces(beforeVersionId) || filePath.getVirtualFile() == null) {
return false;
}
// apply if base revision id matches revision
final VirtualFile root = GitUtil.getGitRoot(filePath);

final SHAHash shaHash = GitChangeUtils.commitExists(myProject, root, beforeVersionId, null, "HEAD");
if (shaHash == null) {
throw new VcsException("Can not apply patch to " + filePath.getPath() + ".\nCan not find revision '" + beforeVersionId + "'.");
}

final ContentRevision content = GitVcs.getInstance(myProject).getDiffProvider()
.createFileContent(new GitRevisionNumber(shaHash.getValue()), filePath.getVirtualFile());
if (content == null) {
throw new VcsException("Can not load content of '" + filePath.getPath() + "' for revision '" + shaHash.getValue() + "'");
}
return !processor.test(content.getContent());
}

@Override
public void reportAppendableHistory(final FilePath path, final VcsAppendableHistorySessionPartner partner) throws VcsException {
final VcsAbstractHistorySession emptySession = createSession(path, Collections.<VcsFileRevision>emptyList(), null);
partner.reportCreatedEmptySession(emptySession);

VcsConfiguration vcsConfiguration = VcsConfiguration.getInstance(myProject);
String[] additionalArgs = vcsConfiguration.LIMIT_HISTORY ?
new String[]{"--max-count=" + vcsConfiguration.MAXIMUM_HISTORY_ROWS} :
ArrayUtil.EMPTY_STRING_ARRAY;

final GitExecutableValidator validator = GitVcs.getInstance(myProject).getExecutableValidator();
GitHistoryUtils.history(
myProject,
refreshPath(path),
null,
partner::acceptRevision,
e -> {
if (validator.checkExecutableAndNotifyIfNeeded()) {
partner.reportException(e);
}
},
additionalArgs
);
}

/**
* Refreshes the IO File inside this FilePath to let it survive moves.
*/
@Nonnull
private static FilePath refreshPath(@Nonnull FilePath path) {
VirtualFile virtualFile = path.getVirtualFile();
if (virtualFile == null) {
return path;
}
return VcsContextFactory.getInstance().createFilePathOn(virtualFile);
}

@Override
public boolean supportsHistoryForDirectories() {
return true;
}

@Override
public DiffFromHistoryHandler getHistoryDiffHandler() {
return new GitDiffFromHistoryHandler(myProject);
}

@Override
public boolean canShowHistoryFor(@Nonnull VirtualFile file) {
GitRepositoryManager manager = GitUtil.getRepositoryManager(myProject);
GitRepository repository = manager.getRepositoryForFile(file);
return repository != null && !repository.isFresh();
}
}
Loading
Loading