diff --git a/plugin/src/main/java/consulo/git/util/LazyDebug.java b/plugin/src/main/java/consulo/git/util/LazyDebug.java new file mode 100644 index 0000000..7759d6e --- /dev/null +++ b/plugin/src/main/java/consulo/git/util/LazyDebug.java @@ -0,0 +1,16 @@ +package consulo.git.util; + +import jakarta.annotation.Nonnull; + +import java.util.function.Supplier; + +/** + * @author UNV + * @since 2025-11-21 + */ +public final record LazyDebug(@Nonnull Supplier stringSupplier) { + @Override + public String toString() { + return stringSupplier.get(); + } +} diff --git a/plugin/src/main/java/git4idea/DialogManager.java b/plugin/src/main/java/git4idea/DialogManager.java index ae8f0bb..efe5ccd 100644 --- a/plugin/src/main/java/git4idea/DialogManager.java +++ b/plugin/src/main/java/git4idea/DialogManager.java @@ -5,13 +5,13 @@ import consulo.annotation.component.ServiceImpl; import consulo.ide.ServiceManager; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.DialogWrapper; import consulo.ui.ex.awt.Messages; import consulo.ui.image.Image; -import jakarta.inject.Singleton; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import jakarta.inject.Singleton; /** * Use {@link DialogManager#show(DialogWrapper) DialogManager.show(DialogWrapper)} instead of {@link DialogWrapper#show()} @@ -25,71 +25,92 @@ @ServiceAPI(ComponentScope.APPLICATION) @ServiceImpl public class DialogManager { - public static void show(@Nonnull DialogWrapper dialog) { - dialogManager().showDialog(dialog); - } + @RequiredUIAccess + public static void show(@Nonnull DialogWrapper dialog) { + dialogManager().showDialog(dialog); + } - public static int showMessage(@Nonnull final String description, - @Nonnull final String title, - @Nonnull final String[] options, - final int defaultButtonIndex, - final int focusedButtonIndex, - @Nullable final Image icon, - @Nullable final DialogWrapper.DoNotAskOption dontAskOption) { - return dialogManager().showMessageDialog(description, title, options, defaultButtonIndex, focusedButtonIndex, icon, dontAskOption); - } + @RequiredUIAccess + public static int showMessage( + @Nonnull String description, + @Nonnull String title, + @Nonnull String[] options, + int defaultButtonIndex, + int focusedButtonIndex, + @Nullable Image icon, + @Nullable DialogWrapper.DoNotAskOption dontAskOption + ) { + return dialogManager().showMessageDialog(description, title, options, defaultButtonIndex, focusedButtonIndex, icon, dontAskOption); + } - public static int showOkCancelDialog(@Nonnull Project project, - @Nonnull String message, - @Nonnull String title, - @Nonnull String okButtonText, - @Nonnull String cancelButtonText, - @Nullable Image icon) { - return dialogManager().showMessageDialog(project, message, title, new String[]{ - okButtonText, - cancelButtonText - }, 0, icon); - } + public static int showOkCancelDialog( + @Nonnull Project project, + @Nonnull String message, + @Nonnull String title, + @Nonnull String okButtonText, + @Nonnull String cancelButtonText, + @Nullable Image icon + ) { + return dialogManager().showMessageDialog(project, message, title, new String[]{ + okButtonText, + cancelButtonText + }, 0, icon); + } - public static int showYesNoCancelDialog(@Nonnull Project project, - @Nonnull String message, - @Nonnull String title, - @Nonnull String yesButtonText, - @Nonnull String noButtonText, - @Nonnull String cancelButtonText, - @Nullable Image icon) { - return dialogManager().showMessageDialog(project, message, title, new String[]{ - yesButtonText, - noButtonText, - cancelButtonText - }, 0, icon); - } + public static int showYesNoCancelDialog( + @Nonnull Project project, + @Nonnull String message, + @Nonnull String title, + @Nonnull String yesButtonText, + @Nonnull String noButtonText, + @Nonnull String cancelButtonText, + @Nullable Image icon + ) { + return dialogManager().showMessageDialog( + project, + message, + title, + new String[]{ + yesButtonText, + noButtonText, + cancelButtonText + }, + 0, + icon + ); + } - protected void showDialog(@Nonnull DialogWrapper dialog) { - dialog.show(); - } + @RequiredUIAccess + protected void showDialog(@Nonnull DialogWrapper dialog) { + dialog.show(); + } - protected int showMessageDialog(@Nonnull Project project, - @Nonnull String message, - @Nonnull String title, - @Nonnull String[] options, - int defaultButtonIndex, - @Nullable Image icon) { - return Messages.showDialog(project, message, title, options, defaultButtonIndex, icon); - } + protected int showMessageDialog( + @Nonnull Project project, + @Nonnull String message, + @Nonnull String title, + @Nonnull String[] options, + int defaultButtonIndex, + @Nullable Image icon + ) { + return Messages.showDialog(project, message, title, options, defaultButtonIndex, icon); + } - protected int showMessageDialog(@Nonnull String description, - @Nonnull String title, - @Nonnull String[] options, - int defaultButtonIndex, - int focusedButtonIndex, - @Nullable Image icon, - @Nullable DialogWrapper.DoNotAskOption dontAskOption) { - return Messages.showDialog(description, title, options, defaultButtonIndex, focusedButtonIndex, icon, dontAskOption); - } + @RequiredUIAccess + protected int showMessageDialog( + @Nonnull String description, + @Nonnull String title, + @Nonnull String[] options, + int defaultButtonIndex, + int focusedButtonIndex, + @Nullable Image icon, + @Nullable DialogWrapper.DoNotAskOption dontAskOption + ) { + return Messages.showDialog(description, title, options, defaultButtonIndex, focusedButtonIndex, icon, dontAskOption); + } - @Nonnull - private static DialogManager dialogManager() { - return ServiceManager.getService(DialogManager.class); - } + @Nonnull + private static DialogManager dialogManager() { + return ServiceManager.getService(DialogManager.class); + } } diff --git a/plugin/src/main/java/git4idea/GitBranchesSearcher.java b/plugin/src/main/java/git4idea/GitBranchesSearcher.java index d5eff2c..2e68c28 100644 --- a/plugin/src/main/java/git4idea/GitBranchesSearcher.java +++ b/plugin/src/main/java/git4idea/GitBranchesSearcher.java @@ -16,55 +16,58 @@ package git4idea; -import consulo.logging.Logger; import consulo.project.Project; import consulo.versionControlSystem.VcsException; import consulo.virtualFileSystem.VirtualFile; import git4idea.branch.GitBranchUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.HashSet; import java.util.Set; public class GitBranchesSearcher { - private final static Logger LOG = Logger.getInstance(GitBranchesSearcher.class); - private final GitBranch myLocal; - private GitBranch myRemote; + private final static Logger LOG = LoggerFactory.getLogger(GitBranchesSearcher.class); + private final GitBranch myLocal; + private GitBranch myRemote; - public GitBranchesSearcher(final Project project, final VirtualFile root, final boolean findRemote) throws VcsException { - LOG.debug("constructing, root: " + root.getPath() + " findRemote = " + findRemote); - final Set usedBranches = new HashSet(); - myLocal = GitBranchUtil.getCurrentBranch(project, root); - LOG.debug("local: " + myLocal); - if (myLocal == null) return; - usedBranches.add(myLocal); + public GitBranchesSearcher(Project project, VirtualFile root, boolean findRemote) throws VcsException { + LOG.debug("constructing, root: {} findRemote = {}", root.getPath(), findRemote); + Set usedBranches = new HashSet<>(); + myLocal = GitBranchUtil.getCurrentBranch(project, root); + LOG.debug("local: {}", myLocal); + if (myLocal == null) { + return; + } + usedBranches.add(myLocal); - GitBranch remote = myLocal; - while (true) { - remote = GitBranchUtil.tracked(project, root, remote.getName()); - if (remote == null) { - LOG.debug("remote == null, exiting"); - return; - } + GitBranch remote = myLocal; + while (true) { + remote = GitBranchUtil.tracked(project, root, remote.getName()); + if (remote == null) { + LOG.debug("remote == null, exiting"); + return; + } - if ((! findRemote) || remote.isRemote()) { - LOG.debug("remote found, isRemote: " + remote.isRemote() + " remoteName: " + remote.getFullName()); - myRemote = remote; - return; - } + if (!findRemote || remote.isRemote()) { + LOG.debug("remote found, isRemote: {} remoteName: {}", remote.isRemote(), remote.getFullName()); + myRemote = remote; + return; + } - if (usedBranches.contains(remote)) { - LOG.debug("loop found for: " + remote.getFullName() + ", exiting"); - return; - } - usedBranches.add(remote); + if (usedBranches.contains(remote)) { + LOG.debug("loop found for: {}, exiting", remote.getFullName()); + return; + } + usedBranches.add(remote); + } } - } - public GitBranch getLocal() { - return myLocal; - } + public GitBranch getLocal() { + return myLocal; + } - public GitBranch getRemote() { - return myRemote; - } + public GitBranch getRemote() { + return myRemote; + } } diff --git a/plugin/src/main/java/git4idea/GitUserRegistry.java b/plugin/src/main/java/git4idea/GitUserRegistry.java index 7fc9b71..259b52f 100644 --- a/plugin/src/main/java/git4idea/GitUserRegistry.java +++ b/plugin/src/main/java/git4idea/GitUserRegistry.java @@ -18,14 +18,11 @@ import consulo.annotation.component.ComponentScope; import consulo.annotation.component.ServiceAPI; import consulo.annotation.component.ServiceImpl; -import consulo.application.ApplicationManager; import consulo.disposer.Disposable; import consulo.ide.ServiceManager; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.collection.ContainerUtil; import consulo.util.lang.StringUtil; -import consulo.util.lang.function.Condition; import consulo.versionControlSystem.ProjectLevelVcsManager; import consulo.versionControlSystem.VcsException; import consulo.versionControlSystem.VcsListener; @@ -33,11 +30,13 @@ import consulo.versionControlSystem.log.VcsUser; import consulo.virtualFileSystem.VirtualFile; import git4idea.config.GitConfigUtil; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import jakarta.inject.Inject; import jakarta.inject.Singleton; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import jakarta.annotation.Nonnull; -import jakarta.annotation.Nullable; import java.util.Collection; import java.util.Map; @@ -45,90 +44,81 @@ @ServiceAPI(ComponentScope.PROJECT) @ServiceImpl public class GitUserRegistry implements Disposable, VcsListener { + private static final Logger LOG = LoggerFactory.getLogger(GitUserRegistry.class); - private static final Logger LOG = Logger.getInstance(GitUserRegistry.class); + @Nonnull + private final Project myProject; + @Nonnull + private final ProjectLevelVcsManager myVcsManager; + @Nonnull + private final VcsLogObjectsFactory myFactory; + @Nonnull + private final Map myUserMap = ContainerUtil.newConcurrentMap(); - @Nonnull - private final Project myProject; - @Nonnull - private final ProjectLevelVcsManager myVcsManager; - @Nonnull - private final VcsLogObjectsFactory myFactory; - @Nonnull - private final Map myUserMap = ContainerUtil.newConcurrentMap(); - - @Inject - public GitUserRegistry(@Nonnull Project project, @Nonnull ProjectLevelVcsManager vcsManager, @Nonnull VcsLogObjectsFactory factory) { - myProject = project; - myVcsManager = vcsManager; - myFactory = factory; - } + @Inject + public GitUserRegistry(@Nonnull Project project, @Nonnull ProjectLevelVcsManager vcsManager, @Nonnull VcsLogObjectsFactory factory) { + myProject = project; + myVcsManager = vcsManager; + myFactory = factory; + } - public static GitUserRegistry getInstance(@Nonnull Project project) { - return ServiceManager.getService(project, GitUserRegistry.class); - } + public static GitUserRegistry getInstance(@Nonnull Project project) { + return ServiceManager.getService(project, GitUserRegistry.class); + } - public void activate() { - myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); - directoryMappingChanged(); - } + public void activate() { + myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this); + directoryMappingChanged(); + } - @Nullable - public VcsUser getUser(@Nonnull VirtualFile root) { - return myUserMap.get(root); - } + @Nullable + public VcsUser getUser(@Nonnull VirtualFile root) { + return myUserMap.get(root); + } - @Nullable - public VcsUser getOrReadUser(@Nonnull VirtualFile root) { - VcsUser user = myUserMap.get(root); - if (user == null) { - try { - user = readCurrentUser(myProject, root); - if (user != null) { - myUserMap.put(root, user); + @Nullable + public VcsUser getOrReadUser(@Nonnull VirtualFile root) { + VcsUser user = myUserMap.get(root); + if (user == null) { + try { + user = readCurrentUser(myProject, root); + if (user != null) { + myUserMap.put(root, user); + } + } + catch (VcsException e) { + LOG.warn("Could not retrieve user name in {}", root, e); + } } - } - catch (VcsException e) { - LOG.warn("Could not retrieve user name in " + root, e); - } + return user; } - return user; - } - @Nullable - private VcsUser readCurrentUser(@Nonnull Project project, @Nonnull VirtualFile root) throws VcsException { - String userName = GitConfigUtil.getValue(project, root, GitConfigUtil.USER_NAME); - String userEmail = StringUtil.notNullize(GitConfigUtil.getValue(project, root, GitConfigUtil.USER_EMAIL)); - return userName == null ? null : myFactory.createUser(userName, userEmail); - } - - @Override - public void dispose() { - myUserMap.clear(); - } + @Nullable + private VcsUser readCurrentUser(@Nonnull Project project, @Nonnull VirtualFile root) throws VcsException { + String userName = GitConfigUtil.getValue(project, root, GitConfigUtil.USER_NAME); + String userEmail = StringUtil.notNullize(GitConfigUtil.getValue(project, root, GitConfigUtil.USER_EMAIL)); + return userName == null ? null : myFactory.createUser(userName, userEmail); + } - @Override - public void directoryMappingChanged() { - GitVcs vcs = GitVcs.getInstance(myProject); - if (vcs == null) { - return; + @Override + public void dispose() { + myUserMap.clear(); } - final VirtualFile[] roots = myVcsManager.getRootsUnderVcs(vcs); - final Collection rootsToCheck = ContainerUtil.filter(roots, new Condition() { - @Override - public boolean value(VirtualFile root) { - return getUser(root) == null; - } - }); - if (!rootsToCheck.isEmpty()) { - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - public void run() { - for (VirtualFile root : rootsToCheck) { - getOrReadUser(root); - } + + @Override + public void directoryMappingChanged() { + GitVcs vcs = GitVcs.getInstance(myProject); + if (vcs == null) { + return; + } + VirtualFile[] roots = myVcsManager.getRootsUnderVcs(vcs); + Collection rootsToCheck = ContainerUtil.filter(roots, root -> getUser(root) == null); + if (!rootsToCheck.isEmpty()) { + myProject.getApplication().executeOnPooledThread((Runnable) () -> { + for (VirtualFile root : rootsToCheck) { + getOrReadUser(root); + } + }); } - }); } - } - } diff --git a/plugin/src/main/java/git4idea/GitUtil.java b/plugin/src/main/java/git4idea/GitUtil.java index 9ee7370..6d527a9 100644 --- a/plugin/src/main/java/git4idea/GitUtil.java +++ b/plugin/src/main/java/git4idea/GitUtil.java @@ -19,7 +19,6 @@ import consulo.application.progress.Task; import consulo.git.localize.GitLocalize; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.DialogBuilder; @@ -59,6 +58,8 @@ import git4idea.util.StringScanner; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -98,7 +99,7 @@ private GitRepositoryNotFoundException(@Nonnull FilePath filePath) { public static final String MERGE_HEAD = "MERGE_HEAD"; private static final String SUBMODULE_REPO_PATH_PREFIX = "gitdir:"; - private final static Logger LOG = Logger.getInstance(GitUtil.class); + private final static Logger LOG = LoggerFactory.getLogger(GitUtil.class); private static final String HEAD_FILE = "HEAD"; private static final Pattern HASH_STRING_PATTERN = Pattern.compile("[a-fA-F0-9]{40}"); @@ -193,7 +194,7 @@ private static String readContent(@Nonnull VirtualFile dotGit) { content = readFile(dotGit); } catch (IOException e) { - LOG.error("Couldn't read the content of " + dotGit, e); + LOG.error("Couldn't read the content of {}", dotGit, e); return null; } return content; @@ -210,7 +211,7 @@ public static String readFile(@Nonnull VirtualFile file) throws IOException { return new String(file.contentsToByteArray()); } catch (IOException e) { - LOG.info(String.format("IOException while reading %s (attempt #%s)", file, attempt)); + LOG.info("IOException while reading {} (attempt #{})", file, attempt); if (attempt >= ATTEMPTS - 1) { throw e; } @@ -337,7 +338,7 @@ public static Date parseTimestampWithNFEReport(String value, GitHandler handler, return parseTimestamp(value); } catch (NumberFormatException e) { - LOG.error("annotate(). NFE. Handler: " + handler + ". Output: " + gitOutput, e); + LOG.error("annotate(). NFE. Handler: {}. Output: {}", handler, gitOutput, e); return new Date(); } } @@ -565,7 +566,7 @@ public static void getLocalCommittedChanges( parametersSpecifier.accept(h); String output = h.run(); - LOG.debug("getLocalCommittedChanges output: '" + output + "'"); + LOG.debug("getLocalCommittedChanges output: '{}'", output); StringScanner s = new StringScanner(output); StringBuilder sb = new StringBuilder(); boolean firstStep = true; @@ -797,7 +798,7 @@ public static Collection getRepositoriesFromRoots( for (VirtualFile root : roots) { GitRepository repo = repositoryManager.getRepositoryForRoot(root); if (repo == null) { - LOG.error("Repository not found for root " + root); + LOG.error("Repository not found for root {}", root); } else { repositories.add(repo); @@ -823,7 +824,7 @@ public static Collection getPathsDiffBetweenRefs( String range = beforeRef + ".." + afterRef; GitCommandResult result = git.diff(repository, parameters, range); if (!result.success()) { - LOG.info(String.format("Couldn't get diff in range [%s] for repository [%s]", range, repository.toLogString())); + LOG.info("Couldn't get diff in range [{}] for repository [{}]", range, repository.toLogString()); return Collections.emptyList(); } @@ -849,7 +850,7 @@ public static GitRepository getRepositoryForRootOrLogError(@Nonnull Project proj GitRepositoryManager manager = getRepositoryManager(project); GitRepository repository = manager.getRepositoryForRoot(root); if (repository == null) { - LOG.error("Repository is null for root " + root); + LOG.error("Repository is null for root {}", root); } return repository; } @@ -957,7 +958,7 @@ public static VirtualFile findRefreshFileOrLog(@Nonnull String absolutePath) { file = LocalFileSystem.getInstance().refreshAndFindFileByPath(absolutePath); } if (file == null) { - LOG.warn("VirtualFile not found for " + absolutePath); + LOG.warn("VirtualFile not found for {}", absolutePath); } return file; } @@ -990,21 +991,18 @@ public static List findLocalChangesForPaths( for (String path : affectedPaths) { String absolutePath = relativePaths ? toAbsolute(root, path) : path; VirtualFile file = findRefreshFileOrLog(absolutePath); - if (file != null) { - Change change = changeListManager.getChange(file); - if (change != null) { - affectedChanges.add(change); - } - else { - String message = "Change is not found for " + file.getPath(); - if (changeListManager.isInUpdate()) { - message += " because ChangeListManager is being updated."; - LOG.debug(message); - } - else { - LOG.info(message); - } - } + if (file == null) { + continue; + } + Change change = changeListManager.getChange(file); + if (change != null) { + affectedChanges.add(change); + } + else if (changeListManager.isInUpdate()) { + LOG.debug("Change is not found for {} because ChangeListManager is being updated.", file.getPath()); + } + else { + LOG.info("Change is not found for {}", file.getPath()); } } return affectedChanges; @@ -1102,7 +1100,7 @@ public static Collection getRepositoriesInState(@Nonnull Project public static boolean isCaseOnlyChange(@Nonnull String oldPath, @Nonnull String newPath) { if (oldPath.equalsIgnoreCase(newPath)) { if (oldPath.equals(newPath)) { - LOG.error("Comparing perfectly equal paths: " + newPath); + LOG.error("Comparing perfectly equal paths: {}", newPath); } return true; } diff --git a/plugin/src/main/java/git4idea/GitVcs.java b/plugin/src/main/java/git4idea/GitVcs.java index bd67438..098f520 100644 --- a/plugin/src/main/java/git4idea/GitVcs.java +++ b/plugin/src/main/java/git4idea/GitVcs.java @@ -26,7 +26,6 @@ import consulo.git.localize.GitLocalize; import consulo.ide.setting.ShowSettingsUtil; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.platform.Platform; import consulo.project.Project; import consulo.project.ui.notification.Notification; @@ -78,6 +77,8 @@ import jakarta.annotation.Nullable; import jakarta.inject.Inject; import jakarta.inject.Singleton; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.swing.event.HyperlinkEvent; import java.io.File; @@ -97,7 +98,7 @@ public class GitVcs extends AbstractVcs { public static final String NAME = "Git"; public static final String ID = "git"; - private static final Logger log = Logger.getInstance(GitVcs.class); + private static final Logger LOG = LoggerFactory.getLogger(GitVcs.class); private static final VcsKey ourKey = createKey(NAME); private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS"); @@ -272,7 +273,7 @@ public VcsRevisionNumber parseRevisionNumber(@Nullable String revision, @Nullabl return GitRevisionNumber.resolve(myProject, root, revision); } catch (VcsException e) { - log.info("Unexpected problem with resolving the git revision number: ", e); + LOG.info("Unexpected problem with resolving the git revision number: ", e); throw e; } } @@ -404,7 +405,7 @@ public void checkVersion() { try { myVersion = GitVersion.identifyVersion(executable); if (!myVersion.isSupported()) { - log.info("Unsupported Git version: " + myVersion); + LOG.info("Unsupported Git version: {}", myVersion); final String SETTINGS_LINK = "settings"; final String UPDATE_LINK = "update"; String message = String.format( diff --git a/plugin/src/main/java/git4idea/actions/GitResolveConflictsAction.java b/plugin/src/main/java/git4idea/actions/GitResolveConflictsAction.java index 95ad118..b5d03b7 100644 --- a/plugin/src/main/java/git4idea/actions/GitResolveConflictsAction.java +++ b/plugin/src/main/java/git4idea/actions/GitResolveConflictsAction.java @@ -29,7 +29,6 @@ import consulo.virtualFileSystem.status.FileStatus; import git4idea.GitUtil; import git4idea.GitVcs; -import git4idea.actions.GitAction; import git4idea.repo.GitRepository; import jakarta.annotation.Nonnull; diff --git a/plugin/src/main/java/git4idea/annotate/GitAnnotationProvider.java b/plugin/src/main/java/git4idea/annotate/GitAnnotationProvider.java index 94266b5..76a5906 100644 --- a/plugin/src/main/java/git4idea/annotate/GitAnnotationProvider.java +++ b/plugin/src/main/java/git4idea/annotate/GitAnnotationProvider.java @@ -23,7 +23,6 @@ import consulo.application.progress.ProgressManager; import consulo.git.localize.GitLocalize; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.lang.StringUtil; import consulo.versionControlSystem.FilePath; @@ -45,6 +44,8 @@ import jakarta.annotation.Nonnull; import jakarta.inject.Inject; import jakarta.inject.Singleton; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Date; import java.util.HashMap; @@ -60,9 +61,12 @@ @ServiceAPI(ComponentScope.PROJECT) @ServiceImpl public class GitAnnotationProvider implements AnnotationProvider, VcsCacheableAnnotationProvider { + private static final Logger LOG = LoggerFactory.getLogger(GitAnnotationProvider.class); + /** * the context project */ + @Nonnull private final Project myProject; /** * The author key for annotations @@ -72,7 +76,6 @@ public class GitAnnotationProvider implements AnnotationProvider, VcsCacheableAn * The committer time key for annotations */ private static final String COMMITTER_TIME_KEY = "committer-time"; - private static final Logger LOG = Logger.getInstance(GitAnnotationProvider.class); /** * A constructor @@ -98,21 +101,21 @@ public FileAnnotation annotate(@Nonnull VirtualFile file) throws VcsException { */ @Nonnull @Override - public FileAnnotation annotate(@Nonnull final VirtualFile file, final VcsFileRevision revision) throws VcsException { + public FileAnnotation annotate(@Nonnull VirtualFile file, VcsFileRevision revision) throws VcsException { if (file.isDirectory()) { throw new VcsException("Cannot annotate a directory"); } - final FileAnnotation[] annotation = new FileAnnotation[1]; - final Exception[] exception = new Exception[1]; + FileAnnotation[] annotation = new FileAnnotation[1]; + Exception[] exception = new Exception[1]; Runnable command = () -> { - final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); try { - final FilePath currentFilePath = VcsUtil.getFilePath(file.getPath()); - final FilePath realFilePath; + FilePath currentFilePath = VcsUtil.getFilePath(file.getPath()); + FilePath realFilePath; if (progress != null) { progress.setTextValue(GitLocalize.gettingHistory(file.getName())); } - final List revisions = GitHistoryUtils.history(myProject, currentFilePath); + List revisions = GitHistoryUtils.history(myProject, currentFilePath); if (revision == null) { realFilePath = GitHistoryUtils.getLastCommitName(myProject, currentFilePath); } @@ -122,7 +125,7 @@ public FileAnnotation annotate(@Nonnull final VirtualFile file, final VcsFileRev if (progress != null) { progress.setTextValue(GitLocalize.computingAnnotation(file.getName())); } - final GitFileAnnotation result = annotate(realFilePath, revision, revisions, file); + GitFileAnnotation result = annotate(realFilePath, revision, revisions, file); annotation[0] = result; } catch (Exception e) { @@ -130,14 +133,13 @@ public FileAnnotation annotate(@Nonnull final VirtualFile file, final VcsFileRev } }; if (Application.get().isDispatchThread()) { - ProgressManager.getInstance() - .runProcessWithProgressSynchronously(command, GitLocalize.annotateActionName().get(), false, myProject); + ProgressManager.getInstance().runProcessWithProgressSynchronously(command, GitLocalize.annotateActionName(), false, myProject); } else { command.run(); } if (exception[0] != null) { - LOG.warn(exception[0]); + LOG.warn("Failed to annotate", exception[0]); throw new VcsException("Failed to annotate: " + exception[0], exception[0]); } return annotation[0]; @@ -154,10 +156,10 @@ public FileAnnotation annotate(@Nonnull final VirtualFile file, final VcsFileRev * @throws VcsException if there is a problem with running git */ private GitFileAnnotation annotate( - final FilePath repositoryFilePath, - final VcsFileRevision revision, - final List revisions, - final VirtualFile file + FilePath repositoryFilePath, + VcsFileRevision revision, + List revisions, + VirtualFile file ) throws VcsException { GitSimpleHandler h = new GitSimpleHandler(myProject, GitUtil.getGitRoot(repositoryFilePath), GitCommand.BLAME); h.setStdoutSuppressed(true); @@ -229,9 +231,9 @@ class CommitInfo { @Override public VcsAnnotation createCacheable(FileAnnotation fileAnnotation) { - final GitFileAnnotation gitFileAnnotation = (GitFileAnnotation)fileAnnotation; - final int size = gitFileAnnotation.getNumLines(); - final VcsUsualLineAnnotationData basicData = new VcsUsualLineAnnotationData(size); + GitFileAnnotation gitFileAnnotation = (GitFileAnnotation)fileAnnotation; + int size = gitFileAnnotation.getNumLines(); + VcsUsualLineAnnotationData basicData = new VcsUsualLineAnnotationData(size); for (int i = 0; i < size; i++) { basicData.put(i, gitFileAnnotation.getLineRevisionNumber(i)); } @@ -246,17 +248,16 @@ public FileAnnotation restore( boolean forCurrentRevision, VcsRevisionNumber revisionNumber ) { - final GitFileAnnotation gitFileAnnotation = + GitFileAnnotation gitFileAnnotation = new GitFileAnnotation(myProject, vcsAnnotation.getFilePath().getVirtualFile(), forCurrentRevision, revisionNumber); gitFileAnnotation.addLogEntries(session.getRevisionList()); - final VcsLineAnnotationData basicAnnotation = vcsAnnotation.getBasicAnnotation(); - final int size = basicAnnotation.getNumLines(); - final Map historyAsMap = session.getHistoryAsMap(); - final List lines = - StringUtil.split(StringUtil.convertLineSeparators(annotatedContent), "\n", false, false); + VcsLineAnnotationData basicAnnotation = vcsAnnotation.getBasicAnnotation(); + int size = basicAnnotation.getNumLines(); + Map historyAsMap = session.getHistoryAsMap(); + List lines = StringUtil.split(StringUtil.convertLineSeparators(annotatedContent), "\n", false, false); for (int i = 0; i < size; i++) { - final VcsRevisionNumber revision = basicAnnotation.getRevision(i); - final VcsFileRevision vcsFileRevision = historyAsMap.get(revision); + VcsRevisionNumber revision = basicAnnotation.getRevision(i); + VcsFileRevision vcsFileRevision = historyAsMap.get(revision); if (vcsFileRevision == null) { return null; } diff --git a/plugin/src/main/java/git4idea/annotate/GitFileAnnotation.java b/plugin/src/main/java/git4idea/annotate/GitFileAnnotation.java index 449e5c6..174ec7f 100644 --- a/plugin/src/main/java/git4idea/annotate/GitFileAnnotation.java +++ b/plugin/src/main/java/git4idea/annotate/GitFileAnnotation.java @@ -18,7 +18,6 @@ import consulo.application.util.DateFormatUtil; import consulo.git.localize.GitLocalize; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.versionControlSystem.AbstractVcsHelper; import consulo.versionControlSystem.VcsException; @@ -43,8 +42,6 @@ * Based on the JetBrains SVNAnnotationProvider. */ public class GitFileAnnotation extends FileAnnotation { - private final static Logger LOG = Logger.getInstance(GitFileAnnotation.class); - /** * annotated content */ @@ -71,7 +68,7 @@ public class GitFileAnnotation extends FileAnnotation { private final LineAnnotationAspect DATE_ASPECT = new GitAnnotationAspect(GitAnnotationAspect.DATE, true) { @Override public String doGetValue(LineInfo info) { - final Date date = info.getDate(); + Date date = info.getDate(); return date == null ? "" : DateFormatUtil.formatPrettyDate(date); } }; @@ -79,7 +76,7 @@ public String doGetValue(LineInfo info) { private final LineAnnotationAspect REVISION_ASPECT = new GitAnnotationAspect(GitAnnotationAspect.REVISION, false) { @Override protected String doGetValue(LineInfo lineInfo) { - final GitRevisionNumber revision = lineInfo.getRevision(); + GitRevisionNumber revision = lineInfo.getRevision(); return revision == null ? "" : String.valueOf(revision.getShortRev()); } }; @@ -87,7 +84,7 @@ protected String doGetValue(LineInfo lineInfo) { private final LineAnnotationAspect AUTHOR_ASPECT = new GitAnnotationAspect(GitAnnotationAspect.AUTHOR, true) { @Override protected String doGetValue(LineInfo lineInfo) { - final String author = lineInfo.getAuthor(); + String author = lineInfo.getAuthor(); return author == null ? "" : author; } }; @@ -102,10 +99,10 @@ protected String doGetValue(LineInfo lineInfo) { * @param revision */ public GitFileAnnotation( - @Nonnull final Project project, + @Nonnull Project project, @Nonnull VirtualFile file, - final boolean monitorFlag, - final VcsRevisionNumber revision + boolean monitorFlag, + VcsRevisionNumber revision ) { super(project); myProject = project; @@ -150,7 +147,7 @@ public LocalizeValue getToolTipValue(int lineNumber) { if (myLines.size() <= lineNumber || lineNumber < 0) { return LocalizeValue.empty(); } - final LineInfo info = myLines.get(lineNumber); + LineInfo info = myLines.get(lineNumber); if (info == null) { return LocalizeValue.empty(); } @@ -181,7 +178,7 @@ public String getAnnotatedContent() { */ @Override public List getRevisions() { - final List result = new ArrayList<>(myRevisionMap.values()); + List result = new ArrayList<>(myRevisionMap.values()); Collections.sort(result, (o1, o2) -> -1 * o1.getRevisionNumber().compareTo(o2.getRevisionNumber())); return result; } @@ -205,11 +202,11 @@ public int getLineCount() { * {@inheritDoc} */ @Override - public VcsRevisionNumber getLineRevisionNumber(final int lineNumber) { + public VcsRevisionNumber getLineRevisionNumber(int lineNumber) { if (lineNumberCheck(lineNumber)) { return null; } - final LineInfo lineInfo = myLines.get(lineNumber); + LineInfo lineInfo = myLines.get(lineNumber); return lineInfo == null ? null : lineInfo.getRevision(); } @@ -222,7 +219,7 @@ public Date getLineDate(int lineNumber) { if (lineNumberCheck(lineNumber)) { return null; } - final LineInfo lineInfo = myLines.get(lineNumber); + LineInfo lineInfo = myLines.get(lineNumber); return lineInfo == null ? null : lineInfo.getDate(); } @@ -245,11 +242,11 @@ public VcsRevisionNumber originalRevision(int lineNumber) { * @throws VcsException in case when line could not be processed */ public void appendLineInfo( - final Date date, - final GitRevisionNumber revision, - final String author, - final String line, - final long lineNumber + Date date, + GitRevisionNumber revision, + String author, + String line, + long lineNumber ) throws VcsException { int expectedLineNo = myLines.size() + 1; if (lineNumber != expectedLineNo) { @@ -281,7 +278,7 @@ public String getValue(int lineNumber) { @Override protected void showAffectedPaths(int lineNum) { if (lineNum >= 0 && lineNum < myLines.size()) { - final LineInfo info = myLines.get(lineNum); + LineInfo info = myLines.get(lineNum); if (info != null) { AbstractVcsHelper.getInstance(myProject).showSubmittedFiles(info.getRevision(), myFile, GitVcs.getKey()); } @@ -313,7 +310,7 @@ static class LineInfo { * @param revision revision number * @param author the author of the change */ - public LineInfo(final Date date, final GitRevisionNumber revision, final String author) { + public LineInfo(Date date, GitRevisionNumber revision, String author) { myDate = date; myRevision = revision; myAuthor = author; @@ -359,7 +356,7 @@ public VcsKey getVcsKey() { @Override public boolean isBaseRevisionChanged(@Nonnull VcsRevisionNumber number) { - final VcsRevisionNumber currentCurrentRevision = myVcs.getDiffProvider().getCurrentRevision(myFile); + VcsRevisionNumber currentCurrentRevision = myVcs.getDiffProvider().getCurrentRevision(myFile); return myBaseRevision != null && !myBaseRevision.equals(currentCurrentRevision); } } diff --git a/plugin/src/main/java/git4idea/branch/DeepComparator.java b/plugin/src/main/java/git4idea/branch/DeepComparator.java index 886a279..9f31f2f 100644 --- a/plugin/src/main/java/git4idea/branch/DeepComparator.java +++ b/plugin/src/main/java/git4idea/branch/DeepComparator.java @@ -20,7 +20,6 @@ import consulo.disposer.Disposable; import consulo.disposer.Disposer; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.NotificationService; import consulo.ui.annotation.RequiredUIAccess; @@ -39,6 +38,8 @@ import git4idea.repo.GitRepositoryManager; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.HashSet; @@ -46,7 +47,7 @@ import java.util.Set; public class DeepComparator implements VcsLogDeepComparator, Disposable { - private static final Logger LOG = Logger.getInstance(DeepComparator.class); + private static final Logger LOG = LoggerFactory.getLogger(DeepComparator.class); @Nonnull private final Project myProject; @@ -257,7 +258,7 @@ public void run(@Nonnull ProgressIndicator indicator) { } } catch (VcsException e) { - LOG.warn(e); + LOG.warn("Error while collecting non-picked commits", e); myException = e; } } @@ -312,7 +313,7 @@ public void onLineAvailable(String line, Key outputType) { pickedCommits.add(new CommitId(hash, root)); } catch (Exception e) { - LOG.error("Couldn't parse line [" + line + "]"); + LOG.error("Couldn't parse line [{}]", line); } } } diff --git a/plugin/src/main/java/git4idea/branch/GitBranchIsNotFullyMergedDialog.java b/plugin/src/main/java/git4idea/branch/GitBranchIsNotFullyMergedDialog.java index 0f0dc3e..44b6534 100644 --- a/plugin/src/main/java/git4idea/branch/GitBranchIsNotFullyMergedDialog.java +++ b/plugin/src/main/java/git4idea/branch/GitBranchIsNotFullyMergedDialog.java @@ -15,8 +15,9 @@ */ package git4idea.branch; -import consulo.logging.Logger; +import consulo.localize.LocalizeValue; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.DialogWrapper; import consulo.ui.ex.awt.JBLabel; import consulo.util.collection.ArrayUtil; @@ -26,12 +27,10 @@ import git4idea.repo.GitRepository; import git4idea.ui.GitCommitListWithDiffPanel; import git4idea.ui.GitRepositoryComboboxListCellRenderer; - import jakarta.annotation.Nonnull; + import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -43,161 +42,146 @@ * * @author Kirill Likhodedov */ -public class GitBranchIsNotFullyMergedDialog extends DialogWrapper -{ - - private static final Logger LOG = Logger.getInstance(GitBranchIsNotFullyMergedDialog.class); - - private final Project myProject; - private final Map> myCommits; - - private final GitCommitListWithDiffPanel myCommitListWithDiffPanel; - private final Collection myRepositories; - @Nonnull - private final String myRemovedBranch; - @Nonnull - private final Map myBaseBranches; - private final GitRepository myInitialRepository; - - /** - * Show the dialog and get user's answer, whether he wants to force delete the branch. - * - * @param commits the list of commits, which are not merged from the branch being deleted to the current branch, - * grouped by repository. - * @param baseBranches base branches (which Git reported as not containing commits from the removed branch) per repository. - * @return true if user decided to restore the branch. - */ - public static boolean showAndGetAnswer(@Nonnull Project project, - @Nonnull Map> commits, - @Nonnull Map baseBranches, - @Nonnull String removedBranch) - { - GitBranchIsNotFullyMergedDialog dialog = new GitBranchIsNotFullyMergedDialog(project, commits, baseBranches, removedBranch); - DialogManager.show(dialog); - return dialog.isOK(); - } - - private GitBranchIsNotFullyMergedDialog(@Nonnull Project project, - @Nonnull Map> commits, - @Nonnull Map baseBranches, - @Nonnull String removedBranch) - { - super(project, false); - myProject = project; - myCommits = commits; - myRepositories = commits.keySet(); - myBaseBranches = baseBranches; - myRemovedBranch = removedBranch; - - myInitialRepository = calcInitiallySelectedRepository(); - myCommitListWithDiffPanel = new GitCommitListWithDiffPanel(myProject, new ArrayList<>(myCommits.get(myInitialRepository))); - - init(); - - setTitle("Branch Was Not Fully Merged"); - setOKButtonText("Restore"); - setOKButtonMnemonic('R'); - getCancelAction().putValue(DEFAULT_ACTION, Boolean.TRUE); - } - - @Nonnull - private GitRepository calcInitiallySelectedRepository() - { - for(GitRepository repository : myRepositories) - { - if(!myCommits.get(repository).isEmpty()) - { - return repository; - } - } - throw new AssertionError("The dialog shouldn't be shown. Unmerged commits: " + myCommits); - } - - @Nonnull - private String makeDescription(@Nonnull GitRepository repository) - { - String baseBranch = myBaseBranches.get(repository); - String description; - if(baseBranch == null) - { - description = String.format("All commits from branch %s were merged", myRemovedBranch); - } - else - { - description = String.format("The branch %s was not fully merged to %s.
Below is the list of unmerged commits.", myRemovedBranch, baseBranch); - } - return XmlStringUtil.wrapInHtml(description); - } - - @Override - protected JComponent createNorthPanel() - { - JBLabel descriptionLabel = new JBLabel(makeDescription(myInitialRepository)); - - JComboBox repositorySelector = new JComboBox(ArrayUtil.toObjectArray(myRepositories, GitRepository.class)); - repositorySelector.setRenderer(new GitRepositoryComboboxListCellRenderer(repositorySelector)); - repositorySelector.setSelectedItem(myInitialRepository); - repositorySelector.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - GitRepository selectedRepo = (GitRepository) repositorySelector.getSelectedItem(); - descriptionLabel.setText(makeDescription(selectedRepo)); - myCommitListWithDiffPanel.setCommits(myCommits.get(selectedRepo)); - } - }); - - JPanel repoSelectorPanel = new JPanel(new BorderLayout()); - JBLabel label = new JBLabel("Repository: "); - label.setLabelFor(repoSelectorPanel); - repoSelectorPanel.add(label, BorderLayout.WEST); - repoSelectorPanel.add(repositorySelector); - - if(myRepositories.size() < 2) - { - repoSelectorPanel.setVisible(false); - } - - JPanel northPanel = new JPanel(new BorderLayout()); - northPanel.add(descriptionLabel); - northPanel.add(repoSelectorPanel, BorderLayout.SOUTH); - return northPanel; - } - - @Override - protected JComponent createCenterPanel() - { - JPanel rootPanel = new JPanel(new BorderLayout()); - rootPanel.add(myCommitListWithDiffPanel); - return rootPanel; - } - - @Nonnull - @Override - protected Action[] createLeftSideActions() - { - return new Action[]{getOKAction()}; - } - - @Nonnull - @Override - protected Action[] createActions() - { - Action cancelAction = getCancelAction(); - cancelAction.putValue(DEFAULT_ACTION, Boolean.TRUE); - return new Action[]{cancelAction}; - } - - @Override - public JComponent getPreferredFocusedComponent() - { - return myCommitListWithDiffPanel.getPreferredFocusComponent(); - } - - @Override - protected String getDimensionServiceKey() - { - return GitBranchIsNotFullyMergedDialog.class.getName(); - } +public class GitBranchIsNotFullyMergedDialog extends DialogWrapper { + private final Project myProject; + private final Map> myCommits; + + private final GitCommitListWithDiffPanel myCommitListWithDiffPanel; + private final Collection myRepositories; + @Nonnull + private final String myRemovedBranch; + @Nonnull + private final Map myBaseBranches; + private final GitRepository myInitialRepository; + + /** + * Show the dialog and get user's answer, whether he wants to force delete the branch. + * + * @param commits the list of commits, which are not merged from the branch being deleted to the current branch, + * grouped by repository. + * @param baseBranches base branches (which Git reported as not containing commits from the removed branch) per repository. + * @return true if user decided to restore the branch. + */ + public static boolean showAndGetAnswer( + @Nonnull Project project, + @Nonnull Map> commits, + @Nonnull Map baseBranches, + @Nonnull String removedBranch + ) { + GitBranchIsNotFullyMergedDialog dialog = new GitBranchIsNotFullyMergedDialog(project, commits, baseBranches, removedBranch); + DialogManager.show(dialog); + return dialog.isOK(); + } + + private GitBranchIsNotFullyMergedDialog( + @Nonnull Project project, + @Nonnull Map> commits, + @Nonnull Map baseBranches, + @Nonnull String removedBranch + ) { + super(project, false); + myProject = project; + myCommits = commits; + myRepositories = commits.keySet(); + myBaseBranches = baseBranches; + myRemovedBranch = removedBranch; + + myInitialRepository = calcInitiallySelectedRepository(); + myCommitListWithDiffPanel = new GitCommitListWithDiffPanel(myProject, new ArrayList<>(myCommits.get(myInitialRepository))); + + init(); + + setTitle(LocalizeValue.localizeTODO("Branch Was Not Fully Merged")); + setOKButtonText(LocalizeValue.localizeTODO("Restore")); + setOKButtonMnemonic('R'); + getCancelAction().putValue(DEFAULT_ACTION, Boolean.TRUE); + } + + @Nonnull + private GitRepository calcInitiallySelectedRepository() { + for (GitRepository repository : myRepositories) { + if (!myCommits.get(repository).isEmpty()) { + return repository; + } + } + throw new AssertionError("The dialog shouldn't be shown. Unmerged commits: " + myCommits); + } + + @Nonnull + private String makeDescription(@Nonnull GitRepository repository) { + String baseBranch = myBaseBranches.get(repository); + String description; + if (baseBranch == null) { + description = String.format("All commits from branch %s were merged", myRemovedBranch); + } + else { + description = String.format( + "The branch %s was not fully merged to %s.
Below is the list of unmerged commits.", + myRemovedBranch, + baseBranch + ); + } + return XmlStringUtil.wrapInHtml(description); + } + + @Override + protected JComponent createNorthPanel() { + JBLabel descriptionLabel = new JBLabel(makeDescription(myInitialRepository)); + + JComboBox repositorySelector = new JComboBox<>(ArrayUtil.toObjectArray(myRepositories, GitRepository.class)); + repositorySelector.setRenderer(new GitRepositoryComboboxListCellRenderer(repositorySelector)); + repositorySelector.setSelectedItem(myInitialRepository); + repositorySelector.addActionListener(e -> { + GitRepository selectedRepo = (GitRepository) repositorySelector.getSelectedItem(); + descriptionLabel.setText(makeDescription(selectedRepo)); + myCommitListWithDiffPanel.setCommits(myCommits.get(selectedRepo)); + }); + + JPanel repoSelectorPanel = new JPanel(new BorderLayout()); + JBLabel label = new JBLabel("Repository: "); + label.setLabelFor(repoSelectorPanel); + repoSelectorPanel.add(label, BorderLayout.WEST); + repoSelectorPanel.add(repositorySelector); + + if (myRepositories.size() < 2) { + repoSelectorPanel.setVisible(false); + } + + JPanel northPanel = new JPanel(new BorderLayout()); + northPanel.add(descriptionLabel); + northPanel.add(repoSelectorPanel, BorderLayout.SOUTH); + return northPanel; + } + + @Override + protected JComponent createCenterPanel() { + JPanel rootPanel = new JPanel(new BorderLayout()); + rootPanel.add(myCommitListWithDiffPanel); + return rootPanel; + } + + @Nonnull + @Override + protected Action[] createLeftSideActions() { + return new Action[]{getOKAction()}; + } + + @Nonnull + @Override + protected Action[] createActions() { + Action cancelAction = getCancelAction(); + cancelAction.putValue(DEFAULT_ACTION, Boolean.TRUE); + return new Action[]{cancelAction}; + } + + @Override + @RequiredUIAccess + public JComponent getPreferredFocusedComponent() { + return myCommitListWithDiffPanel.getPreferredFocusComponent(); + } + + @Override + protected String getDimensionServiceKey() { + return GitBranchIsNotFullyMergedDialog.class.getName(); + } } diff --git a/plugin/src/main/java/git4idea/branch/GitBranchWorker.java b/plugin/src/main/java/git4idea/branch/GitBranchWorker.java index 64cb15c..6fb78fe 100644 --- a/plugin/src/main/java/git4idea/branch/GitBranchWorker.java +++ b/plugin/src/main/java/git4idea/branch/GitBranchWorker.java @@ -15,20 +15,13 @@ */ package git4idea.branch; -import java.util.Collection; -import java.util.List; - -import jakarta.annotation.Nonnull; - -import consulo.application.ApplicationManager; -import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.Messages; +import consulo.util.collection.ContainerUtil; import consulo.util.lang.Couple; import consulo.versionControlSystem.VcsException; import consulo.versionControlSystem.change.Change; -import consulo.util.collection.ContainerUtil; -import consulo.util.lang.function.Condition; import git4idea.GitCommit; import git4idea.GitExecutionException; import git4idea.GitLocalBranch; @@ -39,191 +32,186 @@ import git4idea.repo.GitRepository; import git4idea.ui.branch.GitCompareBranchesDialog; import git4idea.util.GitCommitCompareInfo; +import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.List; /** * Executes the logic of git branch operations. * All operations are run in the current thread. * All UI interaction is done via the {@link GitBranchUiHandler} passed to the constructor. */ -public final class GitBranchWorker -{ - - private static final Logger LOG = Logger.getInstance(GitBranchWorker.class); - - @Nonnull - private final Project myProject; - @Nonnull - private final Git myGit; - @Nonnull - private final GitBranchUiHandler myUiHandler; - - public GitBranchWorker(@Nonnull Project project, @Nonnull Git git, @Nonnull GitBranchUiHandler uiHandler) - { - myProject = project; - myGit = git; - myUiHandler = uiHandler; - } - - public void checkoutNewBranch(@Nonnull final String name, @Nonnull List repositories) - { - updateInfo(repositories); - repositories = ContainerUtil.filter(repositories, new Condition() - { - @Override - public boolean value(GitRepository repository) - { - GitLocalBranch currentBranch = repository.getCurrentBranch(); - return currentBranch == null || !currentBranch.getName().equals(name); - } - }); - if(!repositories.isEmpty()) - { - new GitCheckoutNewBranchOperation(myProject, myGit, myUiHandler, repositories, name).execute(); - } - else - { - LOG.error("Creating new branch the same as current in all repositories: " + name); - } - } - - public void createNewTag(@Nonnull final String name, @Nonnull final String reference, @Nonnull final List repositories) - { - for(GitRepository repository : repositories) - { - myGit.createNewTag(repository, name, null, reference); - repository.getRepositoryFiles().refresh(); - } - } - - public void checkoutNewBranchStartingFrom(@Nonnull String newBranchName, @Nonnull String startPoint, @Nonnull List repositories) - { - updateInfo(repositories); - new GitCheckoutOperation(myProject, myGit, myUiHandler, repositories, startPoint, false, true, newBranchName).execute(); - } - - public void checkout(@Nonnull final String reference, boolean detach, @Nonnull List repositories) - { - updateInfo(repositories); - new GitCheckoutOperation(myProject, myGit, myUiHandler, repositories, reference, detach, false, null).execute(); - } - - - public void deleteBranch(@Nonnull final String branchName, @Nonnull final List repositories) - { - updateInfo(repositories); - new GitDeleteBranchOperation(myProject, myGit, myUiHandler, repositories, branchName).execute(); - } - - public void deleteRemoteBranch(@Nonnull final String branchName, @Nonnull final List repositories) - { - updateInfo(repositories); - new GitDeleteRemoteBranchOperation(myProject, myGit, myUiHandler, repositories, branchName).execute(); - } - - public void merge(@Nonnull final String branchName, @Nonnull final GitBrancher.DeleteOnMergeOption deleteOnMerge, @Nonnull final List repositories) - { - updateInfo(repositories); - new GitMergeOperation(myProject, myGit, myUiHandler, repositories, branchName, deleteOnMerge).execute(); - } - - public void rebase(@Nonnull List repositories, @Nonnull String branchName) - { - updateInfo(repositories); - GitRebaseUtils.rebase(myProject, repositories, new GitRebaseParams(branchName), myUiHandler.getProgressIndicator()); - } - - public void rebaseOnCurrent(@Nonnull List repositories, @Nonnull String branchName) - { - updateInfo(repositories); - GitRebaseUtils.rebase(myProject, repositories, new GitRebaseParams(branchName, null, "HEAD", false, false), myUiHandler.getProgressIndicator()); - } - - public void renameBranch(@Nonnull String currentName, @Nonnull String newName, @Nonnull List repositories) - { - updateInfo(repositories); - new GitRenameBranchOperation(myProject, myGit, myUiHandler, currentName, newName, repositories).execute(); - } - - public void compare(@Nonnull final String branchName, @Nonnull final List repositories, @Nonnull final GitRepository selectedRepository) - { - final GitCommitCompareInfo myCompareInfo = loadCommitsToCompare(repositories, branchName); - if(myCompareInfo == null) - { - LOG.error("The task to get compare info didn't finish. Repositories: \n" + repositories + "\nbranch name: " + branchName); - return; - } - ApplicationManager.getApplication().invokeLater(new Runnable() - { - @Override - public void run() - { - displayCompareDialog(branchName, GitBranchUtil.getCurrentBranchOrRev(repositories), myCompareInfo, selectedRepository); - } - }); - } - - private GitCommitCompareInfo loadCommitsToCompare(List repositories, String branchName) - { - GitCommitCompareInfo compareInfo = new GitCommitCompareInfo(); - for(GitRepository repository : repositories) - { - compareInfo.put(repository, loadCommitsToCompare(repository, branchName)); - compareInfo.put(repository, loadTotalDiff(repository, branchName)); - } - return compareInfo; - } - - @Nonnull - private static Collection loadTotalDiff(@Nonnull GitRepository repository, @Nonnull String branchName) - { - try - { - // return git diff between current working directory and branchName: working dir should be displayed as a 'left' one (base) - return GitChangeUtils.getDiffWithWorkingDir(repository.getProject(), repository.getRoot(), branchName, null, true); - } - catch(VcsException e) - { - // we treat it as critical and report an error - throw new GitExecutionException("Couldn't get [git diff " + branchName + "] on repository [" + repository.getRoot() + "]", e); - } - } - - @Nonnull - private Couple> loadCommitsToCompare(@Nonnull GitRepository repository, @Nonnull final String branchName) - { - final List headToBranch; - final List branchToHead; - try - { - headToBranch = GitHistoryUtils.history(myProject, repository.getRoot(), ".." + branchName); - branchToHead = GitHistoryUtils.history(myProject, repository.getRoot(), branchName + ".."); - } - catch(VcsException e) - { - // we treat it as critical and report an error - throw new GitExecutionException("Couldn't get [git log .." + branchName + "] on repository [" + repository.getRoot() + "]", e); - } - return Couple.of(headToBranch, branchToHead); - } - - private void displayCompareDialog(@Nonnull String branchName, @Nonnull String currentBranch, @Nonnull GitCommitCompareInfo compareInfo, @Nonnull GitRepository selectedRepository) - { - if(compareInfo.isEmpty()) - { - Messages.showInfoMessage(myProject, String.format("There are no changes between %s and %s", currentBranch, branchName), "No Changes Detected"); - } - else - { - new GitCompareBranchesDialog(myProject, branchName, currentBranch, compareInfo, selectedRepository).show(); - } - } - - private static void updateInfo(@Nonnull Collection repositories) - { - for(GitRepository repository : repositories) - { - repository.update(); - } - } - +public final class GitBranchWorker { + private static final Logger LOG = LoggerFactory.getLogger(GitBranchWorker.class); + + @Nonnull + private final Project myProject; + @Nonnull + private final Git myGit; + @Nonnull + private final GitBranchUiHandler myUiHandler; + + public GitBranchWorker(@Nonnull Project project, @Nonnull Git git, @Nonnull GitBranchUiHandler uiHandler) { + myProject = project; + myGit = git; + myUiHandler = uiHandler; + } + + public void checkoutNewBranch(@Nonnull String name, @Nonnull List repositories) { + updateInfo(repositories); + repositories = ContainerUtil.filter( + repositories, + repository -> { + GitLocalBranch currentBranch = repository.getCurrentBranch(); + return currentBranch == null || !currentBranch.getName().equals(name); + } + ); + if (!repositories.isEmpty()) { + new GitCheckoutNewBranchOperation(myProject, myGit, myUiHandler, repositories, name).execute(); + } + else { + LOG.error("Creating new branch the same as current in all repositories: {}", name); + } + } + + public void createNewTag(@Nonnull String name, @Nonnull String reference, @Nonnull List repositories) { + for (GitRepository repository : repositories) { + myGit.createNewTag(repository, name, null, reference); + repository.getRepositoryFiles().refresh(); + } + } + + @RequiredUIAccess + public void checkoutNewBranchStartingFrom( + @Nonnull String newBranchName, + @Nonnull String startPoint, + @Nonnull List repositories + ) { + updateInfo(repositories); + new GitCheckoutOperation(myProject, myGit, myUiHandler, repositories, startPoint, false, true, newBranchName).execute(); + } + + @RequiredUIAccess + public void checkout(@Nonnull String reference, boolean detach, @Nonnull List repositories) { + updateInfo(repositories); + new GitCheckoutOperation(myProject, myGit, myUiHandler, repositories, reference, detach, false, null).execute(); + } + + public void deleteBranch(@Nonnull String branchName, @Nonnull List repositories) { + updateInfo(repositories); + new GitDeleteBranchOperation(myProject, myGit, myUiHandler, repositories, branchName).execute(); + } + + public void deleteRemoteBranch(@Nonnull String branchName, @Nonnull List repositories) { + updateInfo(repositories); + new GitDeleteRemoteBranchOperation(myProject, myGit, myUiHandler, repositories, branchName).execute(); + } + + @RequiredUIAccess + public void merge( + @Nonnull String branchName, + @Nonnull GitBrancher.DeleteOnMergeOption deleteOnMerge, + @Nonnull List repositories + ) { + updateInfo(repositories); + new GitMergeOperation(myProject, myGit, myUiHandler, repositories, branchName, deleteOnMerge).execute(); + } + + public void rebase(@Nonnull List repositories, @Nonnull String branchName) { + updateInfo(repositories); + GitRebaseUtils.rebase(myProject, repositories, new GitRebaseParams(branchName), myUiHandler.getProgressIndicator()); + } + + public void rebaseOnCurrent(@Nonnull List repositories, @Nonnull String branchName) { + updateInfo(repositories); + GitRebaseUtils.rebase( + myProject, + repositories, + new GitRebaseParams(branchName, null, "HEAD", false, false), + myUiHandler.getProgressIndicator() + ); + } + + public void renameBranch(@Nonnull String currentName, @Nonnull String newName, @Nonnull List repositories) { + updateInfo(repositories); + new GitRenameBranchOperation(myProject, myGit, myUiHandler, currentName, newName, repositories).execute(); + } + + public void compare( + @Nonnull String branchName, + @Nonnull List repositories, + @Nonnull GitRepository selectedRepository + ) { + GitCommitCompareInfo myCompareInfo = loadCommitsToCompare(repositories, branchName); + myProject.getApplication().invokeLater(() -> displayCompareDialog( + branchName, + GitBranchUtil.getCurrentBranchOrRev(repositories), + myCompareInfo, + selectedRepository + )); + } + + private GitCommitCompareInfo loadCommitsToCompare(List repositories, String branchName) { + GitCommitCompareInfo compareInfo = new GitCommitCompareInfo(); + for (GitRepository repository : repositories) { + compareInfo.put(repository, loadCommitsToCompare(repository, branchName)); + compareInfo.put(repository, loadTotalDiff(repository, branchName)); + } + return compareInfo; + } + + @Nonnull + private static Collection loadTotalDiff(@Nonnull GitRepository repository, @Nonnull String branchName) { + try { + // return git diff between current working directory and branchName: working dir should be displayed as a 'left' one (base) + return GitChangeUtils.getDiffWithWorkingDir(repository.getProject(), repository.getRoot(), branchName, null, true); + } + catch (VcsException e) { + // we treat it as critical and report an error + throw new GitExecutionException("Couldn't get [git diff " + branchName + "] on repository [" + repository.getRoot() + "]", e); + } + } + + @Nonnull + private Couple> loadCommitsToCompare(@Nonnull GitRepository repository, @Nonnull String branchName) { + List headToBranch; + List branchToHead; + try { + headToBranch = GitHistoryUtils.history(myProject, repository.getRoot(), ".." + branchName); + branchToHead = GitHistoryUtils.history(myProject, repository.getRoot(), branchName + ".."); + } + catch (VcsException e) { + // we treat it as critical and report an error + throw new GitExecutionException("Couldn't get [git log .." + branchName + "] on repository [" + repository.getRoot() + "]", e); + } + return Couple.of(headToBranch, branchToHead); + } + + @RequiredUIAccess + private void displayCompareDialog( + @Nonnull String branchName, + @Nonnull String currentBranch, + @Nonnull GitCommitCompareInfo compareInfo, + @Nonnull GitRepository selectedRepository + ) { + if (compareInfo.isEmpty()) { + Messages.showInfoMessage( + myProject, + String.format("There are no changes between %s and %s", currentBranch, branchName), + "No Changes Detected" + ); + } + else { + new GitCompareBranchesDialog(myProject, branchName, currentBranch, compareInfo, selectedRepository).show(); + } + } + + private static void updateInfo(@Nonnull Collection repositories) { + for (GitRepository repository : repositories) { + repository.update(); + } + } } diff --git a/plugin/src/main/java/git4idea/branch/GitDeleteBranchOperation.java b/plugin/src/main/java/git4idea/branch/GitDeleteBranchOperation.java index 7bf023d..8e92dd3 100644 --- a/plugin/src/main/java/git4idea/branch/GitDeleteBranchOperation.java +++ b/plugin/src/main/java/git4idea/branch/GitDeleteBranchOperation.java @@ -19,7 +19,6 @@ import consulo.application.progress.Task; import consulo.ide.ServiceManager; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.Notification; import consulo.project.ui.notification.NotificationAction; @@ -39,6 +38,8 @@ import git4idea.repo.GitRepository; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; import java.util.regex.Matcher; @@ -55,7 +56,7 @@ * current branch are merged to, and makes force delete, if wanted. */ class GitDeleteBranchOperation extends GitBranchOperation { - private static final Logger LOG = Logger.getInstance(GitDeleteBranchOperation.class); + private static final Logger LOG = LoggerFactory.getLogger(GitDeleteBranchOperation.class); static final LocalizeValue RESTORE = LocalizeValue.localizeTODO("Restore"); static final LocalizeValue VIEW_COMMITS = LocalizeValue.localizeTODO("View Commits"); @@ -217,8 +218,11 @@ private GitCompoundResult doRollback() { GitCommandResult setTrackResult = setUpTracking(repository, myBranchName, trackedBranch); if (!setTrackResult.success()) { LOG.warn( - "Couldn't set " + myBranchName + " to track " + trackedBranch + " in " + repository.getRoot().getName() + - ": " + setTrackResult.getErrorOutputAsJoinedString() + "Couldn't set {} to track {} in {}: {}", + myBranchName, + trackedBranch, + repository.getRoot().getName(), + setTrackResult.getErrorOutputAsJoinedString() ); } } @@ -257,8 +261,8 @@ public LocalizeValue getSuccessMessage() { protected LocalizeValue getRollbackProposal() { return LocalizeValue.localizeTODO( "However branch deletion has succeeded for the following " + repositories() + ":
" + - successfulRepositoriesJoined() + - "
You may rollback (recreate " + myBranchName + " in these roots) not to let branches diverge." + successfulRepositoriesJoined() + + "
You may rollback (recreate " + myBranchName + " in these roots) not to let branches diverge." ); } @@ -314,7 +318,7 @@ private static List getUnmergedCommits( return GitHistoryUtils.history(repository.getProject(), repository.getRoot(), range); } catch (VcsException e) { - LOG.warn("Couldn't get `git log " + range + "` in " + getShortRepositoryName(repository), e); + LOG.warn("Couldn't get `git log {}` in {}", range, getShortRepositoryName(repository), e); } return Collections.emptyList(); } diff --git a/plugin/src/main/java/git4idea/branch/GitMergeOperation.java b/plugin/src/main/java/git4idea/branch/GitMergeOperation.java index a130c25..553635b 100644 --- a/plugin/src/main/java/git4idea/branch/GitMergeOperation.java +++ b/plugin/src/main/java/git4idea/branch/GitMergeOperation.java @@ -17,7 +17,6 @@ import consulo.application.AccessToken; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.Notification; import consulo.project.ui.notification.NotificationService; @@ -39,13 +38,15 @@ import git4idea.reset.GitResetMode; import git4idea.util.GitPreservingProcess; import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.swing.event.HyperlinkEvent; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; class GitMergeOperation extends GitBranchOperation { - private static final Logger LOG = Logger.getInstance(GitMergeOperation.class); + private static final Logger LOG = LoggerFactory.getLogger(GitMergeOperation.class); public static final String ROLLBACK_PROPOSAL = "You may rollback (reset to the commit before merging) not to let branches diverge."; @Nonnull @@ -86,7 +87,7 @@ protected void execute() { try (AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject, getOperationName().get())) { while (hasMoreRepositories() && !fatalErrorHappened) { GitRepository repository = next(); - LOG.info("next repository: " + repository); + LOG.info("next repository: {}", repository); VirtualFile root = repository.getRoot(); GitLocalChangesWouldBeOverwrittenDetector localChangesDetector = @@ -140,7 +141,7 @@ else if (untrackedOverwrittenByMerge.wasMessageDetected()) { fatalErrorHappened = true; } else { - LOG.info("Unknown error. " + result); + LOG.info("Unknown error. {}", result); fatalError(getCommonErrorTitle(), result.getErrorOutputAsJoinedValue()); fatalErrorHappened = true; } @@ -298,9 +299,12 @@ else if (thereAreLocalChangesIn(repository)) { } } - LOG.info("for smart rollback: " + DvcsUtil.getShortNames(repositoriesForSmartRollback) + - "; for simple rollback: " + DvcsUtil.getShortNames(repositoriesForSimpleRollback) + - "; for merge rollback: " + DvcsUtil.getShortNames(repositoriesForMergeRollback)); + LOG.info( + "for smart rollback: {}; for simple rollback: {}; for merge rollback: {}", + DvcsUtil.getShortNames(repositoriesForSmartRollback), + DvcsUtil.getShortNames(repositoriesForSimpleRollback), + DvcsUtil.getShortNames(repositoriesForMergeRollback) + ); GitCompoundResult result = smartRollback(repositoriesForSmartRollback); for (GitRepository repository : repositoriesForSimpleRollback) { diff --git a/plugin/src/main/java/git4idea/changes/GitCommittedChangeListProvider.java b/plugin/src/main/java/git4idea/changes/GitCommittedChangeListProvider.java index eaaef6d..a0971a0 100644 --- a/plugin/src/main/java/git4idea/changes/GitCommittedChangeListProvider.java +++ b/plugin/src/main/java/git4idea/changes/GitCommittedChangeListProvider.java @@ -16,7 +16,6 @@ package git4idea.changes; import consulo.application.util.function.AsynchConsumer; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.io.FileUtil; import consulo.util.lang.Pair; @@ -39,9 +38,10 @@ import git4idea.history.browser.GitHeavyCommit; import git4idea.history.browser.SymbolicRefs; import git4idea.repo.GitRepository; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.util.*; @@ -50,215 +50,199 @@ /** * The provider for committed change lists */ -public class GitCommittedChangeListProvider implements CommittedChangesProvider -{ - private static final Logger LOG = Logger.getInstance(GitCommittedChangeListProvider.class); - - @Nonnull - private final Project myProject; - - public GitCommittedChangeListProvider(@Nonnull Project project) - { - myProject = project; - } - - @Override - @Nonnull - public ChangeBrowserSettings createDefaultSettings() - { - return new ChangeBrowserSettings(); - } - - @Override - public RepositoryLocation getLocationFor(@Nonnull FilePath root) - { - VirtualFile gitRoot = GitUtil.getGitRootOrNull(root); - if(gitRoot == null) - { - return null; - } - GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(gitRoot); - if(repository == null) - { - LOG.info("No GitRepository for " + gitRoot); - return null; - } - GitLocalBranch currentBranch = repository.getCurrentBranch(); - if(currentBranch == null) - { - return null; - } - GitRemoteBranch trackedBranch = currentBranch.findTrackedBranch(repository); - if(trackedBranch == null) - { - return null; - } - File rootFile = new File(gitRoot.getPath()); - return new GitRepositoryLocation(trackedBranch.getRemote().getFirstUrl(), rootFile); - } - - @Override - public RepositoryLocation getLocationFor(FilePath root, String repositoryPath) - { - return getLocationFor(root); - } - - @Override - @Nullable - public VcsCommittedListsZipper getZipper() - { - return null; - } - - @Override - public void loadCommittedChanges(ChangeBrowserSettings settings, - RepositoryLocation location, - int maxCount, - final AsynchConsumer consumer) throws VcsException - { - try - { - getCommittedChangesImpl(settings, location, maxCount, gitCommittedChangeList -> consumer.accept(gitCommittedChangeList)); - } - finally - { - consumer.finished(); - } - } - - @Override - public List getCommittedChanges(ChangeBrowserSettings settings, - RepositoryLocation location, - final int maxCount) throws VcsException - { - - final List result = new ArrayList(); - - getCommittedChangesImpl(settings, location, maxCount, committedChangeList -> result.add(committedChangeList)); - - return result; - } - - private void getCommittedChangesImpl(ChangeBrowserSettings settings, - RepositoryLocation location, - final int maxCount, - final Consumer consumer) throws VcsException - { - GitRepositoryLocation l = (GitRepositoryLocation) location; - final Long beforeRev = settings.getChangeBeforeFilter(); - final Long afterRev = settings.getChangeAfterFilter(); - final Date beforeDate = settings.getDateBeforeFilter(); - final Date afterDate = settings.getDateAfterFilter(); - final String author = settings.getUserFilter(); - VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot()); - if(root == null) - { - throw new VcsException("The repository does not exists anymore: " + l.getRoot()); - } - - GitUtil.getLocalCommittedChanges(myProject, root, h -> - { - if(!StringUtil.isEmpty(author)) - { - h.addParameters("--author=" + author); - } - if(beforeDate != null) - { - h.addParameters("--before=" + GitUtil.gitTime(beforeDate)); - } - if(afterDate != null) - { - h.addParameters("--after=" + GitUtil.gitTime(afterDate)); - } - if(maxCount != getUnlimitedCountValue()) - { - h.addParameters("-n" + maxCount); - } - if(beforeRev != null && afterRev != null) - { - h.addParameters(GitUtil.formatLongRev(afterRev) + ".." + GitUtil.formatLongRev(beforeRev)); - } - else if(beforeRev != null) - { - h.addParameters(GitUtil.formatLongRev(beforeRev)); - } - else if(afterRev != null) - { - h.addParameters(GitUtil.formatLongRev(afterRev) + ".."); - } - }, consumer, false); - } - - @Override - public ChangeListColumn[] getColumns() - { - return new ChangeListColumn[]{ - ChangeListColumn.NUMBER, - ChangeListColumn.DATE, - ChangeListColumn.DESCRIPTION, - ChangeListColumn.NAME - }; - } - - @Override - public VcsCommittedViewAuxiliary createActions(DecoratorManager manager, RepositoryLocation location) - { - return null; - } - - @Override - public int getUnlimitedCountValue() - { - return -1; - } - - @Override - public Pair getOneList(final VirtualFile file, final VcsRevisionNumber number) throws VcsException - { - final FilePath filePath = VcsContextFactory.getInstance().createFilePathOn(file); - - final List gitCommits = GitHistoryUtils.commitsDetails(myProject, filePath, new SymbolicRefs(), - Collections.singletonList(number.asString())); - if(gitCommits.size() != 1) - { - return null; - } - final GitHeavyCommit gitCommit = gitCommits.get(0); - CommittedChangeList commit = new GitCommittedChangeList(gitCommit.getDescription() + " (" + gitCommit.getShortHash().getString() + ")", - gitCommit.getDescription(), gitCommit.getAuthor(), (GitRevisionNumber) number, new Date(gitCommit.getAuthorTime()), - gitCommit.getChanges(), true); - - final Collection changes = commit.getChanges(); - if(changes.size() == 1) - { - Change change = changes.iterator().next(); - return Pair.create(commit, ChangesUtil.getFilePath(change)); - } - for(Change change : changes) - { - if(change.getAfterRevision() != null && FileUtil.filesEqual(filePath.getIOFile(), change.getAfterRevision().getFile().getIOFile())) - { - return new Pair(commit, filePath); - } - } - final String afterTime = "--after=" + GitUtil.gitTime(gitCommit.getDate()); - final List history = GitHistoryUtils.history(myProject, filePath, (VirtualFile) null, afterTime); - if(history.isEmpty()) - { - return new Pair(commit, filePath); - } - return Pair.create(commit, ((GitFileRevision) history.get(history.size() - 1)).getPath()); - } - - @Override - public RepositoryLocation getForNonLocal(VirtualFile file) - { - return null; - } - - @Override - public boolean supportsIncomingChanges() - { - return false; - } +public class GitCommittedChangeListProvider implements CommittedChangesProvider { + private static final Logger LOG = LoggerFactory.getLogger(GitCommittedChangeListProvider.class); + + @Nonnull + private final Project myProject; + + public GitCommittedChangeListProvider(@Nonnull Project project) { + myProject = project; + } + + @Override + @Nonnull + public ChangeBrowserSettings createDefaultSettings() { + return new ChangeBrowserSettings(); + } + + @Override + public RepositoryLocation getLocationFor(@Nonnull FilePath root) { + VirtualFile gitRoot = GitUtil.getGitRootOrNull(root); + if (gitRoot == null) { + return null; + } + GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(gitRoot); + if (repository == null) { + LOG.info("No GitRepository for {}", gitRoot); + return null; + } + GitLocalBranch currentBranch = repository.getCurrentBranch(); + if (currentBranch == null) { + return null; + } + GitRemoteBranch trackedBranch = currentBranch.findTrackedBranch(repository); + if (trackedBranch == null) { + return null; + } + File rootFile = new File(gitRoot.getPath()); + return new GitRepositoryLocation(trackedBranch.getRemote().getFirstUrl(), rootFile); + } + + @Override + public RepositoryLocation getLocationFor(FilePath root, String repositoryPath) { + return getLocationFor(root); + } + + @Override + @Nullable + public VcsCommittedListsZipper getZipper() { + return null; + } + + @Override + public void loadCommittedChanges( + ChangeBrowserSettings settings, + RepositoryLocation location, + int maxCount, + AsynchConsumer consumer + ) throws VcsException { + try { + getCommittedChangesImpl(settings, location, maxCount, consumer::accept); + } + finally { + consumer.finished(); + } + } + + @Override + public List getCommittedChanges(ChangeBrowserSettings settings, RepositoryLocation location, int maxCount) + throws VcsException { + + List result = new ArrayList<>(); + + getCommittedChangesImpl(settings, location, maxCount, result::add); + + return result; + } + + private void getCommittedChangesImpl( + ChangeBrowserSettings settings, + RepositoryLocation location, + int maxCount, + Consumer consumer + ) throws VcsException { + GitRepositoryLocation l = (GitRepositoryLocation) location; + Long beforeRev = settings.getChangeBeforeFilter(); + Long afterRev = settings.getChangeAfterFilter(); + Date beforeDate = settings.getDateBeforeFilter(); + Date afterDate = settings.getDateAfterFilter(); + String author = settings.getUserFilter(); + VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot()); + if (root == null) { + throw new VcsException("The repository does not exists anymore: " + l.getRoot()); + } + + GitUtil.getLocalCommittedChanges( + myProject, + root, + h -> { + if (!StringUtil.isEmpty(author)) { + h.addParameters("--author=" + author); + } + if (beforeDate != null) { + h.addParameters("--before=" + GitUtil.gitTime(beforeDate)); + } + if (afterDate != null) { + h.addParameters("--after=" + GitUtil.gitTime(afterDate)); + } + if (maxCount != getUnlimitedCountValue()) { + h.addParameters("-n" + maxCount); + } + if (beforeRev != null && afterRev != null) { + h.addParameters(GitUtil.formatLongRev(afterRev) + ".." + GitUtil.formatLongRev(beforeRev)); + } + else if (beforeRev != null) { + h.addParameters(GitUtil.formatLongRev(beforeRev)); + } + else if (afterRev != null) { + h.addParameters(GitUtil.formatLongRev(afterRev) + ".."); + } + }, + consumer, + false + ); + } + + @Override + public ChangeListColumn[] getColumns() { + return new ChangeListColumn[]{ + ChangeListColumn.NUMBER, + ChangeListColumn.DATE, + ChangeListColumn.DESCRIPTION, + ChangeListColumn.NAME + }; + } + + @Override + public VcsCommittedViewAuxiliary createActions(DecoratorManager manager, RepositoryLocation location) { + return null; + } + + @Override + public int getUnlimitedCountValue() { + return -1; + } + + @Override + public Pair getOneList(VirtualFile file, VcsRevisionNumber number) throws VcsException { + FilePath filePath = VcsContextFactory.getInstance().createFilePathOn(file); + + List gitCommits = GitHistoryUtils.commitsDetails(myProject, filePath, new SymbolicRefs(), + Collections.singletonList(number.asString()) + ); + if (gitCommits.size() != 1) { + return null; + } + GitHeavyCommit gitCommit = gitCommits.get(0); + CommittedChangeList commit = new GitCommittedChangeList( + gitCommit.getDescription() + " (" + gitCommit.getShortHash().getString() + ")", + gitCommit.getDescription(), + gitCommit.getAuthor(), + (GitRevisionNumber) number, + new Date(gitCommit.getAuthorTime()), + gitCommit.getChanges(), + true + ); + + Collection changes = commit.getChanges(); + if (changes.size() == 1) { + Change change = changes.iterator().next(); + return Pair.create(commit, ChangesUtil.getFilePath(change)); + } + for (Change change : changes) { + if (change.getAfterRevision() != null && FileUtil.filesEqual( + filePath.getIOFile(), + change.getAfterRevision().getFile().getIOFile() + )) { + return Pair.create(commit, filePath); + } + } + String afterTime = "--after=" + GitUtil.gitTime(gitCommit.getDate()); + List history = GitHistoryUtils.history(myProject, filePath, (VirtualFile) null, afterTime); + if (history.isEmpty()) { + return Pair.create(commit, filePath); + } + return Pair.create(commit, ((GitFileRevision) history.get(history.size() - 1)).getPath()); + } + + @Override + public RepositoryLocation getForNonLocal(VirtualFile file) { + return null; + } + + @Override + public boolean supportsIncomingChanges() { + return false; + } } diff --git a/plugin/src/main/java/git4idea/changes/GitOutgoingChangesProvider.java b/plugin/src/main/java/git4idea/changes/GitOutgoingChangesProvider.java index 9d6beba..9966ee8 100644 --- a/plugin/src/main/java/git4idea/changes/GitOutgoingChangesProvider.java +++ b/plugin/src/main/java/git4idea/changes/GitOutgoingChangesProvider.java @@ -15,7 +15,6 @@ */ package git4idea.changes; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.lang.Pair; import consulo.versionControlSystem.FilePath; @@ -34,114 +33,128 @@ import git4idea.GitUtil; import git4idea.history.GitHistoryUtils; import git4idea.history.browser.SHAHash; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.*; public class GitOutgoingChangesProvider implements VcsOutgoingChangesProvider { - private final static Logger LOG = Logger.getInstance(GitOutgoingChangesProvider.class); - private final Project myProject; + private final static Logger LOG = LoggerFactory.getLogger(GitOutgoingChangesProvider.class); + private final Project myProject; - public GitOutgoingChangesProvider(Project project) { - myProject = project; - } - - public Pair> getOutgoingChanges(final VirtualFile vcsRoot, final boolean findRemote) - throws VcsException { - LOG.debug("getOutgoingChanges root: " + vcsRoot.getPath()); - final GitBranchesSearcher searcher = new GitBranchesSearcher(myProject, vcsRoot, findRemote); - if (searcher.getLocal() == null || searcher.getRemote() == null) { - return new Pair>(null, Collections.emptyList()); - } - final GitRevisionNumber base = getMergeBase(myProject, vcsRoot, searcher.getLocal(), searcher.getRemote()); - if (base == null) { - return new Pair>(null, Collections.emptyList()); + public GitOutgoingChangesProvider(Project project) { + myProject = project; } - final List lists = - GitUtil.getLocalCommittedChanges(myProject, vcsRoot, handler -> handler.addParameters(base.asString() + "..HEAD")); - return new Pair<>(base, ObjectsConvertor.convert(lists, o -> o)); - } - @Nullable - public VcsRevisionNumber getMergeBaseNumber(final VirtualFile anyFileUnderRoot) throws VcsException { - LOG.debug("getMergeBaseNumber parameter: " + anyFileUnderRoot.getPath()); - final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); - final VirtualFile root = vcsManager.getVcsRootFor(anyFileUnderRoot); - if (root == null) { - LOG.info("VCS root not found"); - return null; + @Override + public Pair> getOutgoingChanges(VirtualFile vcsRoot, boolean findRemote) + throws VcsException { + LOG.debug("getOutgoingChanges root: " + vcsRoot.getPath()); + GitBranchesSearcher searcher = new GitBranchesSearcher(myProject, vcsRoot, findRemote); + if (searcher.getLocal() == null || searcher.getRemote() == null) { + return new Pair<>(null, Collections.emptyList()); + } + GitRevisionNumber base = getMergeBase(myProject, vcsRoot, searcher.getLocal(), searcher.getRemote()); + if (base == null) { + return new Pair<>(null, Collections.emptyList()); + } + List lists = + GitUtil.getLocalCommittedChanges(myProject, vcsRoot, handler -> handler.addParameters(base.asString() + "..HEAD")); + return new Pair<>(base, ObjectsConvertor.convert(lists, o -> o)); } - final GitBranchesSearcher searcher = new GitBranchesSearcher(myProject, root, true); - if (searcher.getLocal() == null || searcher.getRemote() == null) { - LOG.info("local or remote not found"); - return null; - } - final GitRevisionNumber base = getMergeBase(myProject, root, searcher.getLocal(), searcher.getRemote()); - LOG.debug("found base: " + ((base == null) ? null : base.asString())); - return base; - } + @Nullable + @Override + public VcsRevisionNumber getMergeBaseNumber(VirtualFile anyFileUnderRoot) throws VcsException { + LOG.debug("getMergeBaseNumber parameter: {}", anyFileUnderRoot.getPath()); + ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); + VirtualFile root = vcsManager.getVcsRootFor(anyFileUnderRoot); + if (root == null) { + LOG.info("VCS root not found"); + return null; + } - public Collection filterLocalChangesBasedOnLocalCommits(final Collection localChanges, - final VirtualFile vcsRoot) throws VcsException { - final GitBranchesSearcher searcher = new GitBranchesSearcher(myProject, vcsRoot, true); - if (searcher.getLocal() == null || searcher.getRemote() == null) { - return new ArrayList(localChanges); // no information, better strict approach (see getOutgoingChanges() code) - } - final GitRevisionNumber base; - try { - base = getMergeBase(myProject, vcsRoot, searcher.getLocal(), searcher.getRemote()); - } - catch (VcsException e) { - LOG.info(e); - return new ArrayList(localChanges); - } - if (base == null) { - return new ArrayList(localChanges); // no information, better strict approach (see getOutgoingChanges() code) + GitBranchesSearcher searcher = new GitBranchesSearcher(myProject, root, true); + if (searcher.getLocal() == null || searcher.getRemote() == null) { + LOG.info("local or remote not found"); + return null; + } + GitRevisionNumber base = getMergeBase(myProject, root, searcher.getLocal(), searcher.getRemote()); + LOG.debug("found base: {}", base == null ? null : base.asString()); + return base; } - final List> hashes = GitHistoryUtils.onlyHashesHistory(myProject, - VcsContextFactory.getInstance().createFilePathOn(vcsRoot), - vcsRoot, - (base.asString() + "..HEAD")); - if (hashes.isEmpty()) return Collections.emptyList(); // no local commits - final String first = hashes.get(0).getFirst().getValue(); // optimization - final Set localHashes = new HashSet(); - for (Pair hash : hashes) { - localHashes.add(hash.getFirst().getValue()); - } - final Collection result = new ArrayList(); - for (Change change : localChanges) { - if (change.getBeforeRevision() != null) { - final String changeBeforeRevision = change.getBeforeRevision().getRevisionNumber().asString().trim(); - if (first.equals(changeBeforeRevision) || localHashes.contains(changeBeforeRevision)) { - result.add(change); + @Override + public Collection filterLocalChangesBasedOnLocalCommits(Collection localChanges, VirtualFile vcsRoot) + throws VcsException { + GitBranchesSearcher searcher = new GitBranchesSearcher(myProject, vcsRoot, true); + if (searcher.getLocal() == null || searcher.getRemote() == null) { + return new ArrayList<>(localChanges); // no information, better strict approach (see getOutgoingChanges() code) } - } - } - return result; - } + GitRevisionNumber base; + try { + base = getMergeBase(myProject, vcsRoot, searcher.getLocal(), searcher.getRemote()); + } + catch (VcsException e) { + LOG.info("Error while getting merge base", e); + return new ArrayList<>(localChanges); + } + if (base == null) { + return new ArrayList<>(localChanges); // no information, better strict approach (see getOutgoingChanges() code) + } + List> hashes = GitHistoryUtils.onlyHashesHistory( + myProject, + VcsContextFactory.getInstance().createFilePathOn(vcsRoot), + vcsRoot, + (base.asString() + "..HEAD") + ); - @Nullable - public Date getRevisionDate(VcsRevisionNumber revision, FilePath file) { - if (VcsRevisionNumber.NULL.equals(revision)) return null; - try { - return new Date(GitHistoryUtils.getAuthorTime(myProject, file, revision.asString())); + if (hashes.isEmpty()) { + return Collections.emptyList(); // no local commits + } + String first = hashes.get(0).getFirst().getValue(); // optimization + Set localHashes = new HashSet<>(); + for (Pair hash : hashes) { + localHashes.add(hash.getFirst().getValue()); + } + Collection result = new ArrayList<>(); + for (Change change : localChanges) { + if (change.getBeforeRevision() != null) { + String changeBeforeRevision = change.getBeforeRevision().getRevisionNumber().asString().trim(); + if (first.equals(changeBeforeRevision) || localHashes.contains(changeBeforeRevision)) { + result.add(change); + } + } + } + return result; } - catch (VcsException e) { - return null; + + @Nullable + @Override + public Date getRevisionDate(VcsRevisionNumber revision, FilePath file) { + if (VcsRevisionNumber.NULL.equals(revision)) { + return null; + } + try { + return new Date(GitHistoryUtils.getAuthorTime(myProject, file, revision.asString())); + } + catch (VcsException e) { + return null; + } } - } - /** - * Get a merge base between the current branch and specified branch. - * - * @return the common commit or null if the there is no common commit - */ - @Nullable - private static GitRevisionNumber getMergeBase(@Nonnull Project project, @Nonnull VirtualFile root, - @Nonnull GitBranch currentBranch, @Nonnull GitBranch branch) throws VcsException { - return GitHistoryUtils.getMergeBase(project, root, currentBranch.getFullName(), branch.getFullName()); - } + /** + * Get a merge base between the current branch and specified branch. + * + * @return the common commit or null if the there is no common commit + */ + @Nullable + private static GitRevisionNumber getMergeBase( + @Nonnull Project project, @Nonnull VirtualFile root, + @Nonnull GitBranch currentBranch, @Nonnull GitBranch branch + ) throws VcsException { + return GitHistoryUtils.getMergeBase(project, root, currentBranch.getFullName(), branch.getFullName()); + } } diff --git a/plugin/src/main/java/git4idea/checkin/GitCheckinHandlerFactory.java b/plugin/src/main/java/git4idea/checkin/GitCheckinHandlerFactory.java index 0ae20e5..b2e21a4 100644 --- a/plugin/src/main/java/git4idea/checkin/GitCheckinHandlerFactory.java +++ b/plugin/src/main/java/git4idea/checkin/GitCheckinHandlerFactory.java @@ -21,7 +21,7 @@ import consulo.application.progress.Task; import consulo.git.localize.GitLocalize; import consulo.ide.ServiceManager; -import consulo.logging.Logger; +import consulo.localize.LocalizeValue; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.Messages; @@ -52,6 +52,8 @@ import git4idea.repo.GitRepositoryManager; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; import java.util.concurrent.atomic.AtomicReference; @@ -65,7 +67,7 @@ */ @ExtensionImpl public class GitCheckinHandlerFactory extends VcsCheckinHandlerFactory { - private static final Logger LOG = Logger.getInstance(GitCheckinHandlerFactory.class); + private static final Logger LOG = LoggerFactory.getLogger(GitCheckinHandlerFactory.class); public GitCheckinHandlerFactory() { super(GitVcs.getKey()); @@ -167,7 +169,7 @@ private void setCoreAutoCrlfAttribute(@Nonnull VirtualFile aRoot) { } catch (VcsException e) { // it is not critical: the user just will get the dialog again next time - LOG.warn("Couldn't globally set core.autocrlf in " + aRoot, e); + LOG.warn("Couldn't globally set core.autocrlf in {}", aRoot, e); } } @@ -197,7 +199,7 @@ private ReturnResult checkUserName() { } } catch (VcsException e) { - LOG.error("Couldn't get user.name and user.email for root " + root, e); + LOG.error("Couldn't get user.name and user.email for root {}", root, e); // doing nothing - let commit with possibly empty user.name/email } } @@ -232,7 +234,7 @@ private ReturnResult checkUserName() { } } catch (VcsException e) { - LOG.error("Couldn't get user.name and user.email for root " + root, e); + LOG.error("Couldn't get user.name and user.email for root {}", root, e); // doing nothing - not critical not to find the values for other roots not affected by commit } } @@ -266,9 +268,8 @@ private ReturnResult checkUserName() { } } catch (VcsException e) { - String message = "Couldn't set user.name and user.email"; - LOG.error(message, e); - Messages.showErrorDialog(myPanel.getComponent(), message); + LOG.error("Couldn't set user.name and user.email", e); + Messages.showErrorDialog(myPanel.getComponent(), LocalizeValue.localizeTODO("Couldn't set user.name and user.email").get()); return ReturnResult.CANCEL; } return ReturnResult.COMMIT; diff --git a/plugin/src/main/java/git4idea/cherrypick/GitCherryPicker.java b/plugin/src/main/java/git4idea/cherrypick/GitCherryPicker.java index ef84dcf..37cb190 100644 --- a/plugin/src/main/java/git4idea/cherrypick/GitCherryPicker.java +++ b/plugin/src/main/java/git4idea/cherrypick/GitCherryPicker.java @@ -19,7 +19,6 @@ import consulo.application.AccessToken; import consulo.application.Application; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.Notification; import consulo.project.ui.notification.NotificationService; @@ -60,6 +59,8 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import jakarta.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.swing.event.HyperlinkEvent; import java.io.File; @@ -78,7 +79,7 @@ @ExtensionImpl public class GitCherryPicker extends VcsCherryPicker { - private static final Logger LOG = Logger.getInstance(GitCherryPicker.class); + private static final Logger LOG = LoggerFactory.getLogger(GitCherryPicker.class); @Nonnull private final Project myProject; @@ -104,7 +105,7 @@ public GitCherryPicker(@Nonnull Project project, @Nonnull Git git) { @RequiredUIAccess public void cherryPick(@Nonnull List commits) { Map> commitsInRoots = DvcsUtil.groupCommitsByRoots(myRepositoryManager, commits); - LOG.info("Cherry-picking commits: " + toString(commitsInRoots)); + LOG.info("Cherry-picking commits: {}", new CommitsInRootsDebug(commitsInRoots)); List successfulCommits = new ArrayList<>(); List alreadyPicked = new ArrayList<>(); try (AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject, getActionTitle())) { @@ -120,20 +121,22 @@ public void cherryPick(@Nonnull List commits) { } } - @Nonnull - private static String toString(@Nonnull Map> commitsInRoots) { - return StringUtil.join( - commitsInRoots.keySet(), - repository -> { - String commits = StringUtil.join( - commitsInRoots.get(repository), - details -> details.getId().asString(), - ", " - ); - return getShortRepositoryName(repository) + ": [" + commits + "]"; - }, - "; " - ); + private static record CommitsInRootsDebug(@Nonnull Map> commitsInRoots) { + @Override + public String toString() { + return StringUtil.join( + commitsInRoots.keySet(), + repository -> { + String commits = StringUtil.join( + commitsInRoots.get(repository), + details -> details.getId().asString(), + ", " + ); + return getShortRepositoryName(repository) + ": [" + commits + "]"; + }, + "; " + ); + } } // return true to continue with other roots, false to break execution @@ -347,7 +350,7 @@ private LocalChangeList createChangeListAfterUpdate( } } catch (InterruptedException e) { - LOG.error(e); + LOG.error("Interrupted", e); return null; } @@ -399,7 +402,7 @@ public void onFailure() { } } catch (Throwable t) { - LOG.error(t); + LOG.error("Error while committing cherry-pick", t); commitSucceeded.set(false); sem.release(); } @@ -412,7 +415,7 @@ public void onFailure() { sem.acquire(); } catch (InterruptedException e) { - LOG.error(e); + LOG.error("Interrupted", e); return false; } return commitSucceeded.get(); @@ -444,7 +447,7 @@ public void run() { catch (IOException e) { // if CHERRY_PICK_HEAD is not deleted, the partial commit will fail, and the user will be notified anyway. // So here we just log the fact. It is happens relatively often, maybe some additional solution will follow. - LOG.error(e); + LOG.error("Error while removing cherry-pick head", e); } } }); @@ -588,7 +591,7 @@ public void changesMoved(Collection changes, ChangeList fromList, Change return resultingChangeList.get(); } catch (InterruptedException e) { - LOG.error(e); + LOG.error("Interrupted", e); return null; } finally { diff --git a/plugin/src/main/java/git4idea/commands/GitBinaryHandler.java b/plugin/src/main/java/git4idea/commands/GitBinaryHandler.java index 75575af..59163ab 100644 --- a/plugin/src/main/java/git4idea/commands/GitBinaryHandler.java +++ b/plugin/src/main/java/git4idea/commands/GitBinaryHandler.java @@ -109,9 +109,7 @@ protected void waitForProcess() { setExitCode(exitCode); } catch (InterruptedException e) { - if (LOG.isDebugEnabled()) { - LOG.debug("Ignoring process exception: ", e); - } + LOG.debug("Ignoring process exception: ", e); setExitCode(255); } listeners().processTerminated(getExitCode()); diff --git a/plugin/src/main/java/git4idea/commands/GitHandler.java b/plugin/src/main/java/git4idea/commands/GitHandler.java index 2f81136..72eb8c5 100644 --- a/plugin/src/main/java/git4idea/commands/GitHandler.java +++ b/plugin/src/main/java/git4idea/commands/GitHandler.java @@ -17,9 +17,9 @@ import consulo.component.ProcessCanceledException; import consulo.container.plugin.PluginManager; +import consulo.git.util.LazyDebug; import consulo.http.HttpProxyManager; import consulo.ide.ServiceManager; -import consulo.logging.Logger; import consulo.platform.Platform; import consulo.process.ExecutionException; import consulo.process.cmd.GeneralCommandLine; @@ -49,6 +49,8 @@ import org.jetbrains.git4idea.rt.http.GitAskPassXmlRpcHandler; import org.jetbrains.git4idea.rt.ssh.GitSSHHandler; import org.jetbrains.git4idea.ssh.GitXmlRpcSshService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -65,9 +67,9 @@ * A handler for git commands */ public abstract class GitHandler { - protected static final Logger LOG = Logger.getInstance(GitHandler.class); - protected static final Logger OUTPUT_LOG = Logger.getInstance("#output." + GitHandler.class.getName()); - private static final Logger TIME_LOG = Logger.getInstance("#time." + GitHandler.class.getName()); + protected static final Logger LOG = LoggerFactory.getLogger(GitHandler.class); + protected static final Logger OUTPUT_LOG = LoggerFactory.getLogger("#output." + GitHandler.class.getName()); + private static final Logger TIME_LOG = LoggerFactory.getLogger("#time." + GitHandler.class.getName()); @Nonnull protected final Project myProject; @@ -422,26 +424,21 @@ public synchronized void start() { try { myStartTime = System.currentTimeMillis(); - if (!myProject.isDefault() && !mySilent && (myVcs != null)) { - myVcs.showCommandLine("[" + stringifyWorkingDir() + "] " + printableCommandLine()); - LOG.info("[" + stringifyWorkingDir() + "] " + printableCommandLine()); + if (!myProject.isDefault() && !mySilent && myVcs != null) { + String cmdLine = "[" + stringifyWorkingDir() + "] " + printableCommandLine(); + myVcs.showCommandLine(cmdLine); + LOG.info(cmdLine); } else { - LOG.debug("[" + stringifyWorkingDir() + "] " + printableCommandLine()); + LOG.debug("[{}] {}", new LazyDebug(this::stringifyWorkingDir), new LazyDebug(this::printableCommandLine)); } // setup environment if (isRemote()) { switch (myProjectSettings.getAppSettings().getSshExecutableType()) { - case IDEA_SSH: - setupSshAuthenticator(); - break; - case NATIVE_SSH: - setupHttpAuthenticator(); - break; - case PUTTY: - setupPuttyAuthenticator(); - break; + case IDEA_SSH -> setupSshAuthenticator(); + case NATIVE_SSH -> setupHttpAuthenticator(); + case PUTTY -> setupPuttyAuthenticator(); } } setUpLocale(); @@ -457,7 +454,8 @@ public synchronized void start() { } catch (Throwable t) { if (!myProject.getApplication().isUnitTestMode() || !myProject.isDisposed()) { - LOG.error(t); // will surely happen if called during unit test disposal, because the working dir is simply removed then + // will surely happen if called during unit test disposal, because the working dir is simply removed then + LOG.error("Unexpected error", t); } cleanupEnv(); myListeners.getMulticaster().startFailed(t); @@ -481,7 +479,7 @@ private void setupHttpAuthenticator() throws IOException { myEnv.put(GitAskPassXmlRpcHandler.GIT_ASK_PASS_HANDLER_ENV, myHttpHandler.toString()); int port = service.getXmlRcpPort(); myEnv.put(GitAskPassXmlRpcHandler.GIT_ASK_PASS_PORT_ENV, Integer.toString(port)); - LOG.debug(String.format("handler=%s, port=%s", myHttpHandler, port)); + LOG.debug("handler={}, port={}", myHttpHandler, port); addAuthListener(httpAuthenticator); } @@ -512,7 +510,7 @@ private void setupSshAuthenticator() throws IOException { myEnv.put(GitSSHHandler.SSH_HANDLER_ENV, mySshHandler.toString()); int port = ssh.getXmlRcpPort(); myEnv.put(GitSSHHandler.SSH_PORT_ENV, Integer.toString(port)); - LOG.debug(String.format("handler=%s, port=%s", mySshHandler, port)); + LOG.debug("handler={}, port={}", mySshHandler, port); HttpProxyManager httpProxyManager = HttpProxyManager.getInstance(); boolean useHttpProxy = @@ -544,14 +542,18 @@ private void addAuthListener(@Nonnull final GitHttpAuthenticator authenticator) public void onLineAvailable(String line, Key outputType) { String lowerCaseLine = line.toLowerCase(); if (lowerCaseLine.contains("authentication failed") || lowerCaseLine.contains("403 forbidden")) { - LOG.debug("auth listener: auth failure detected: " + line); + LOG.debug("auth listener: auth failure detected: {}", line); myHttpAuthFailed = true; } } @Override public void processTerminated(int exitCode) { - LOG.debug("auth listener: process terminated. auth failed=" + myHttpAuthFailed + ", cancelled=" + authenticator.wasCancelled()); + LOG.debug( + "auth listener: process terminated. auth failed={}, cancelled={}", + myHttpAuthFailed, + authenticator.wasCancelled() + ); if (authenticator.wasCancelled()) { myHttpAuthFailed = false; } @@ -618,7 +620,7 @@ protected synchronized void setExitCode(int exitCode) { myExitCode = exitCode; } else { - LOG.info("Not setting exit code " + exitCode + ", because it was already set to " + myExitCode); + LOG.info("Not setting exit code {}, because it was already set to {}", exitCode, myExitCode); } } @@ -794,19 +796,14 @@ private void logTime() { if (myStartTime > 0) { long time = System.currentTimeMillis() - myStartTime; if (!TIME_LOG.isDebugEnabled() && time > LONG_TIME) { - LOG.info(String.format( - "git %s took %s ms. Command parameters: %n%s", - myCommand, - time, - myCommandLine.getCommandLineString() - )); + LOG.info("git {} took {} ms. Command parameters:\n{}", myCommand, time, myCommandLine.getCommandLineString()); } else { - TIME_LOG.debug(String.format("git %s took %s ms", myCommand, time)); + TIME_LOG.debug("git {} took {} ms", myCommand, time); } } else { - LOG.debug(String.format("git %s finished.", myCommand)); + LOG.debug("git {} finished.", myCommand); } } diff --git a/plugin/src/main/java/git4idea/commands/GitHandlerUtil.java b/plugin/src/main/java/git4idea/commands/GitHandlerUtil.java index 4dc90cf..f34e298 100644 --- a/plugin/src/main/java/git4idea/commands/GitHandlerUtil.java +++ b/plugin/src/main/java/git4idea/commands/GitHandlerUtil.java @@ -20,7 +20,6 @@ import consulo.application.progress.Task; import consulo.git.localize.GitLocalize; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.util.dataholder.Key; import consulo.util.lang.StringUtil; import consulo.versionControlSystem.VcsException; @@ -36,11 +35,6 @@ * Handler utilities that allow running handlers with progress indicators */ public class GitHandlerUtil { - /** - * The logger instance - */ - private static final Logger LOG = Logger.getInstance(GitHandlerUtil.class); - /** * a private constructor for utility class */ diff --git a/plugin/src/main/java/git4idea/commands/GitHttpGuiAuthenticator.java b/plugin/src/main/java/git4idea/commands/GitHttpGuiAuthenticator.java index aa2efe1..6802339 100644 --- a/plugin/src/main/java/git4idea/commands/GitHttpGuiAuthenticator.java +++ b/plugin/src/main/java/git4idea/commands/GitHttpGuiAuthenticator.java @@ -21,7 +21,7 @@ import consulo.credentialStorage.PasswordSafe; import consulo.credentialStorage.ui.AuthDialog; import consulo.credentialStorage.ui.PasswordSafePromptDialog; -import consulo.logging.Logger; +import consulo.git.util.LazyDebug; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.util.collection.ContainerUtil; @@ -36,6 +36,8 @@ import git4idea.remote.GitRememberedInputs; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; @@ -53,7 +55,7 @@ * @author Kirill Likhodedov */ class GitHttpGuiAuthenticator implements GitHttpAuthenticator { - private static final Logger LOG = Logger.getInstance(GitHttpGuiAuthenticator.class); + private static final Logger LOG = LoggerFactory.getLogger(GitHttpGuiAuthenticator.class); private static final Class PASS_REQUESTER = GitHttpAuthenticator.class; @Nonnull @@ -85,7 +87,7 @@ class GitHttpGuiAuthenticator implements GitHttpAuthenticator { @Override @Nonnull public String askPassword(@Nonnull String url) { - LOG.debug("askPassword. url=" + url + ", passwordKnown=" + (myPassword != null) + ", wasCancelled=" + myWasCancelled); + LOG.debug("askPassword. url={}, passwordKnown={}, wasCancelled={}", url, (myPassword != null), myWasCancelled); if (myPassword != null) { // already asked in askUsername return myPassword; } @@ -99,10 +101,11 @@ public String askPassword(@Nonnull String url) { myDataProvider = authData.first; myPassword = password; LOG.debug( - "askPassword. dataProvider=" + getCurrentDataProviderName() + - ", unifiedUrl= " + getUnifiedUrl(url) + - ", login=" + authData.second.getLogin() + - ", passwordKnown=" + (password != null) + "askPassword. dataProvider={}, unifiedUrl={}, login={}, passwordKnown={}", + getCurrentDataProviderName(), + new LazyDebug(() -> getUnifiedUrl(url)), + authData.second.getLogin(), + (password != null) ); return password; } @@ -117,7 +120,10 @@ public String askPassword(@Nonnull String url) { false, null ); - LOG.debug("askPassword. Password was asked and returned: " + (password == null ? "NULL" : password.isEmpty() ? "EMPTY" : "NOT EMPTY")); + LOG.debug( + "askPassword. Password was asked and returned: {}", + password == null ? "NULL" : password.isEmpty() ? "EMPTY" : "NOT EMPTY" + ); if (password == null) { myWasCancelled = true; return ""; @@ -143,15 +149,20 @@ public String askUsername(@Nonnull String url) { password = authData.second.getPassword(); myDataProvider = authData.first; } - LOG.debug("askUsername. dataProvider=" + getCurrentDataProviderName() + ", unifiedUrl= " + getUnifiedUrl(url) + - ", login=" + login + ", passwordKnown=" + (password != null)); + LOG.debug( + "askUsername. dataProvider={}, unifiedUrl={}, login={}, passwordKnown={}", + getCurrentDataProviderName(), + new LazyDebug(() -> getUnifiedUrl(url)), + login, + (password != null) + ); if (login != null && password != null) { myPassword = password; return login; } AuthenticationData data = showAuthDialog(getDisplayableUrl(url), login); - LOG.debug("askUsername. Showed dialog:" + (data == null ? "OK" : "Cancel")); + LOG.debug("askUsername. Showed dialog: {}", data == null ? "OK" : "Cancel"); if (data == null) { myWasCancelled = true; return ""; @@ -198,7 +209,7 @@ public void saveAuthData() { @Override public void forgetPassword() { - LOG.debug("forgetPassword. dataProvider=" + getCurrentDataProviderName() + ", unifiedUrl=" + myUnifiedUrl); + LOG.debug("forgetPassword. dataProvider={}, unifiedUrl={}", getCurrentDataProviderName(), myUnifiedUrl); if (myDataProvider != null && myUnifiedUrl != null) { myDataProvider.forgetPassword(myUnifiedUrl); } diff --git a/plugin/src/main/java/git4idea/commands/GitImpl.java b/plugin/src/main/java/git4idea/commands/GitImpl.java index 563684f..a3e08e1 100644 --- a/plugin/src/main/java/git4idea/commands/GitImpl.java +++ b/plugin/src/main/java/git4idea/commands/GitImpl.java @@ -16,7 +16,6 @@ package git4idea.commands; import consulo.annotation.component.ServiceImpl; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.collection.ContainerUtil; import consulo.util.dataholder.Key; @@ -35,10 +34,12 @@ import git4idea.repo.GitRemote; import git4idea.repo.GitRepository; import git4idea.reset.GitResetMode; -import jakarta.inject.Singleton; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import jakarta.inject.Singleton; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -58,752 +59,795 @@ @Singleton @ServiceImpl public class GitImpl implements Git { + private static final Logger LOG = LoggerFactory.getLogger(Git.class); - private static final Logger LOG = Logger.getInstance(Git.class); - - public GitImpl() { - } - - /** - * Calls 'git init' on the specified directory. - */ - @Nonnull - @Override - public GitCommandResult init(@Nonnull Project project, @Nonnull VirtualFile root, @Nonnull GitLineHandlerListener... listeners) { - GitLineHandler h = new GitLineHandler(project, root, GitCommand.INIT); - for (GitLineHandlerListener listener : listeners) { - h.addLineListener(listener); - } - h.setSilent(false); - h.setStdoutSuppressed(false); - return run(h); - } - - /** - *

Queries Git for the unversioned files in the given paths.

- *

Ignored files are left ignored, i. e. no information is returned about them (thus this method may also be used as a - * ignored files checker.

- * - * @param files files that are to be checked for the unversioned files among them. - * Pass null to query the whole repository. - * @return Unversioned not ignored files from the given scope. - */ - @Override - @Nonnull - public Set untrackedFiles(@Nonnull Project project, - @Nonnull VirtualFile root, - @Nullable Collection files) throws VcsException { - final Set untrackedFiles = new HashSet<>(); - - if (files == null) { - untrackedFiles.addAll(untrackedFilesNoChunk(project, root, null)); - } - else { - for (List relativePaths : VcsFileUtil.chunkFiles(root, files)) { - untrackedFiles.addAll(untrackedFilesNoChunk(project, root, relativePaths)); - } - } - - return untrackedFiles; - } - - // relativePaths are guaranteed to fit into command line length limitations. - @Override - @Nonnull - public Collection untrackedFilesNoChunk(@Nonnull Project project, - @Nonnull VirtualFile root, - @Nullable List relativePaths) throws VcsException { - final Set untrackedFiles = new HashSet<>(); - GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LS_FILES); - h.setSilent(true); - h.addParameters("--exclude-standard", "--others", "-z"); - h.endOptions(); - if (relativePaths != null) { - h.addParameters(relativePaths); - } - - final String output = h.run(); - if (StringUtil.isEmptyOrSpaces(output)) { - return untrackedFiles; - } - - for (String relPath : output.split("\u0000")) { - VirtualFile f = root.findFileByRelativePath(relPath); - if (f == null) { - // files was created on disk, but VirtualFile hasn't yet been created, - // when the GitChangeProvider has already been requested about changes. - LOG.info(String.format("VirtualFile for path [%s] is null", relPath)); - } - else { - untrackedFiles.add(f); - } - } - - return untrackedFiles; - } - - @Override - @Nonnull - public GitCommandResult clone(@Nonnull final Project project, - @Nonnull final File parentDirectory, - @Nonnull final String url, - @Nullable final String puttyKey, - @Nonnull final String clonedDirectoryName, - @Nonnull final GitLineHandlerListener... listeners) { - return run(() -> - { - GitLineHandler handler = new GitLineHandler(project, parentDirectory, GitCommand.CLONE); - handler.setStdoutSuppressed(false); - handler.setUrl(url); - handler.addParameters("--progress"); - handler.addParameters(url); - handler.setPuttyKey(puttyKey); - handler.endOptions(); - handler.addParameters(clonedDirectoryName); - addListeners(handler, listeners); - return handler; - }); - } - - @Nonnull - @Override - public GitCommandResult config(@Nonnull GitRepository repository, String... params) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CONFIG); - h.addParameters(params); - return run(h); - } - - @Nonnull - @Override - public GitCommandResult diff(@Nonnull GitRepository repository, @Nonnull List parameters, @Nonnull String range) { - final GitLineHandler diff = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.DIFF); - diff.addParameters(parameters); - diff.addParameters(range); - diff.setStdoutSuppressed(true); - diff.setStderrSuppressed(true); - diff.setSilent(true); - return run(diff); - } - - @Nonnull - @Override - public GitCommandResult checkAttr(@Nonnull final GitRepository repository, - @Nonnull final Collection attributes, - @Nonnull Collection files) { - List> listOfPaths = VcsFileUtil.chunkFiles(repository.getRoot(), files); - return runAll(ContainerUtil.map(listOfPaths, (Function, Supplier>)relativePaths -> () -> - { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECK_ATTR); - h.addParameters(new ArrayList<>(attributes)); - h.endOptions(); - h.addParameters(relativePaths); - return run(h); - })); - } - - @Nonnull - @Override - public GitCommandResult stashSave(@Nonnull GitRepository repository, @Nonnull String message) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.STASH); - h.addParameters("save"); - h.addParameters(message); - return run(h); - } - - @Nonnull - @Override - public GitCommandResult stashPop(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { - final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.STASH); - handler.addParameters("pop"); - addListeners(handler, listeners); - return run(handler); - } - - @Override - @Nonnull - public GitCommandResult merge(@Nonnull GitRepository repository, - @Nonnull String branchToMerge, - @Nullable List additionalParams, - @Nonnull GitLineHandlerListener... listeners) { - final GitLineHandler mergeHandler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.MERGE); - mergeHandler.setSilent(false); - mergeHandler.addParameters(branchToMerge); - if (additionalParams != null) { - mergeHandler.addParameters(additionalParams); - } - for (GitLineHandlerListener listener : listeners) { - mergeHandler.addLineListener(listener); - } - return run(mergeHandler); - } - - - /** - * {@code git checkout <reference>}
- * {@code git checkout -b <newBranch> <reference>} - */ - @Nonnull - @Override - public GitCommandResult checkout(@Nonnull GitRepository repository, - @Nonnull String reference, - @Nullable String newBranch, - boolean force, - boolean detach, - @Nonnull 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(detach ? reference + "^0" : reference); // we could use `--detach` here, but it is supported only since 1.7.5. - } - else { // checkout reference as new branch - h.addParameters("-b", newBranch, reference); - } - h.endOptions(); - for (GitLineHandlerListener listener : listeners) { - h.addLineListener(listener); - } - return run(h); - } - - /** - * {@code git checkout -b <branchName>} - */ - @Nonnull - @Override - public GitCommandResult checkoutNewBranch(@Nonnull GitRepository repository, - @Nonnull String branchName, - @Nullable GitLineHandlerListener listener) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECKOUT.readLockingCommand()); - h.setSilent(false); - h.setStdoutSuppressed(false); - h.addParameters("-b"); - h.addParameters(branchName); - if (listener != null) { - h.addLineListener(listener); - } - return run(h); - } - - @Nonnull - @Override - public GitCommandResult createNewTag(@Nonnull GitRepository repository, - @Nonnull String tagName, - @Nullable GitLineHandlerListener listener, - @Nonnull String reference) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.TAG); - h.setSilent(false); - h.addParameters(tagName); - if (!reference.isEmpty()) { - h.addParameters(reference); - } - if (listener != null) { - h.addLineListener(listener); - } - return run(h); - } - - /** - * {@code git branch -d } or {@code git branch -D } - */ - @Nonnull - @Override - public GitCommandResult branchDelete(@Nonnull GitRepository repository, - @Nonnull String branchName, - boolean force, - @Nonnull GitLineHandlerListener... listeners) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); - h.setSilent(false); - h.setStdoutSuppressed(false); - h.addParameters(force ? "-D" : "-d"); - h.addParameters(branchName); - for (GitLineHandlerListener listener : listeners) { - h.addLineListener(listener); - } - return run(h); - } - - /** - * Get branches containing the commit. - * {@code git branch --contains } - */ - @Override - @Nonnull - public GitCommandResult branchContains(@Nonnull GitRepository repository, @Nonnull String commit) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); - h.addParameters("--contains", commit); - return run(h); - } - - @Override - @Nonnull - public GitCommandResult branchCreate(@Nonnull GitRepository repository, @Nonnull String branchName, @Nonnull String startPoint) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); - h.setStdoutSuppressed(false); - h.addParameters(branchName); - h.addParameters(startPoint); - return run(h); - } - - @Nonnull - @Override - public GitCommandResult renameBranch(@Nonnull GitRepository repository, - @Nonnull String currentName, - @Nonnull String newName, - @Nonnull GitLineHandlerListener... listeners) { - GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); - h.setStdoutSuppressed(false); - h.addParameters("-m", currentName, newName); - return run(h); - } - - @Override - @Nonnull - public GitCommandResult reset(@Nonnull GitRepository repository, - @Nonnull GitResetMode mode, - @Nonnull String target, - @Nonnull GitLineHandlerListener... listeners) { - return reset(repository, mode.getArgument(), target, listeners); - } - - @Override - @Nonnull - public GitCommandResult resetMerge(@Nonnull GitRepository repository, @Nullable String revision) { - return reset(repository, "--merge", revision); - } - - @Nonnull - private static GitCommandResult reset(@Nonnull GitRepository repository, - @Nonnull String argument, - @Nullable String target, - @Nonnull GitLineHandlerListener... listeners) { - final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.RESET); - handler.addParameters(argument); - if (target != null) { - handler.addParameters(target); - } - addListeners(handler, listeners); - return run(handler); - } - - /** - * Returns the last (tip) commit on the given branch.
- * {@code git rev-list -1 } - */ - @Nonnull - @Override - public GitCommandResult tip(@Nonnull GitRepository repository, @Nonnull String branchName) { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REV_LIST); - h.addParameters("-1"); - h.addParameters(branchName); - return run(h); - } - - @Override - @Nonnull - public GitCommandResult push(@Nonnull GitRepository repository, - @Nonnull String remote, - @Nullable String url, - @Nullable String puttyKey, - @Nonnull String spec, - boolean updateTracking, - @Nonnull GitLineHandlerListener... listeners) { - return doPush(repository, remote, puttyKey, singleton(url), spec, false, updateTracking, false, null, listeners); - } - - @Override - @Nonnull - public GitCommandResult push(@Nonnull GitRepository repository, - @Nonnull GitRemote remote, - @Nonnull String spec, - boolean force, - boolean updateTracking, - boolean skipHook, - @Nullable String tagMode, - GitLineHandlerListener... listeners) { - return doPush(repository, - remote.getName(), - remote.getPuttyKeyFile(), - remote.getPushUrls(), - spec, - force, - updateTracking, - skipHook, - tagMode, - listeners); - } - - @Nonnull - private GitCommandResult doPush(@Nonnull final GitRepository repository, - @Nonnull final String remoteName, - @Nullable String puttyKey, - @Nonnull final Collection remoteUrls, - @Nonnull final String spec, - final boolean force, - final boolean updateTracking, - boolean skipHook, - @Nullable final String tagMode, - @Nonnull final GitLineHandlerListener... listeners) { - return runCommand(() -> - { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.PUSH); - h.setUrls(remoteUrls); - h.setPuttyKey(puttyKey); - h.setSilent(false); - h.setStdoutSuppressed(false); - addListeners(h, listeners); - h.addProgressParameter(); - h.addParameters("--porcelain"); - h.addParameters(remoteName); - h.addParameters(spec); - if (updateTracking) { - h.addParameters("--set-upstream"); - } - if (force) { - h.addParameters("--force"); - } - if (tagMode != null) { - h.addParameters(tagMode); - } - if (skipHook) { - h.addParameters("--no-verify"); - } - return h; - }); - } - - @Nonnull - @Override - public GitCommandResult show(@Nonnull GitRepository repository, @Nonnull String... params) { - final GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.SHOW); - handler.addParameters(params); - return run(handler); - } - - @Override - @Nonnull - public GitCommandResult cherryPick(@Nonnull GitRepository repository, - @Nonnull String hash, - boolean autoCommit, - @Nonnull 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); - handler.setStdoutSuppressed(false); - return run(handler); - } - - @Nonnull - @Override - public GitCommandResult getUnmergedFiles(@Nonnull GitRepository repository) { - GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.LS_FILES); - h.addParameters("--unmerged"); - h.setSilent(true); - return run(h); - } - - /** - * Fetch remote branch - * {@code git fetch } - */ - @Override - @Nonnull - public GitCommandResult fetch(@Nonnull final GitRepository repository, - @Nonnull final GitRemote remote, - @Nonnull final List listeners, - final String... params) { - return runCommand(() -> - { - final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.FETCH); - h.setSilent(false); - h.setStdoutSuppressed(false); - h.setUrls(remote.getUrls()); - h.setPuttyKey(remote.getPuttyKeyFile()); - h.addParameters(remote.getName()); - h.addParameters(params); - h.addProgressParameter(); - GitVcs vcs = GitVcs.getInstance(repository.getProject()); - if (vcs != null && GitVersionSpecialty.SUPPORTS_FETCH_PRUNE.existsIn(vcs.getVersion())) { - h.addParameters("--prune"); - } - addListeners(h, listeners); - return h; - }); - } - - @Nonnull - @Override - public GitCommandResult addRemote(@Nonnull GitRepository repository, @Nonnull String name, @Nonnull String url) { - GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REMOTE); - h.addParameters("add", name, url); - return run(h); - } - - @Nonnull - @Override - public GitCommandResult lsRemote(@Nonnull final Project project, @Nonnull final File workingDir, @Nonnull final String url) { - return doLsRemote(project, workingDir, url, singleton(url)); - } - - @Nonnull - @Override - public GitCommandResult lsRemote(@Nonnull Project project, - @Nonnull VirtualFile workingDir, - @Nonnull GitRemote remote, - String... additionalParameters) { - return doLsRemote(project, VirtualFileUtil.virtualToIoFile(workingDir), remote.getName(), remote.getUrls(), additionalParameters); - } - - @Nonnull - @Override - public GitCommandResult remotePrune(@Nonnull final GitRepository repository, @Nonnull final GitRemote remote) { - return run(() -> - { - GitLineHandler h = - new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REMOTE.writeLockingCommand()); - h.setStdoutSuppressed(false); - h.addParameters("prune"); - h.addParameters(remote.getName()); - h.setUrls(remote.getUrls()); - return h; - }); - } - - @Nonnull - @Override - public GitCommandResult rebase(@Nonnull GitRepository repository, - @Nonnull GitRebaseParams parameters, - @Nonnull GitLineHandlerListener... listeners) { - Project project = repository.getProject(); - VirtualFile root = repository.getRoot(); - GitLineHandler handler = new GitLineHandler(project, root, GitCommand.REBASE); - handler.addParameters(parameters.asCommandLineArguments()); - addListeners(handler, listeners); - return parameters.isInteractive() ? runWithEditor(project, root, handler, true) : run(handler); - } - - @Nonnull - @Override - public GitCommandResult rebaseAbort(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { - GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REBASE); - handler.addParameters("--abort"); - addListeners(handler, listeners); - return run(handler); - } - - @Nonnull - @Override - public GitCommandResult rebaseContinue(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { - return rebaseResume(repository, GitRebaseResumeMode.CONTINUE, listeners); - } - - @Nonnull - @Override - public GitCommandResult rebaseSkip(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { - return rebaseResume(repository, GitRebaseResumeMode.SKIP, listeners); - } - - @Nonnull - private GitCommandResult rebaseResume(@Nonnull GitRepository repository, - @Nonnull GitRebaseResumeMode rebaseMode, - @Nonnull GitLineHandlerListener[] listeners) { - Project project = repository.getProject(); - VirtualFile root = repository.getRoot(); - GitLineHandler handler = new GitLineHandler(project, root, GitCommand.REBASE); - handler.addParameters(rebaseMode.asCommandLineArgument()); - addListeners(handler, listeners); - return runWithEditor(project, root, handler, false); - } - - @Nonnull - private GitCommandResult runWithEditor(@Nonnull Project project, - @Nonnull VirtualFile root, - @Nonnull GitLineHandler handler, - boolean commitListAware) { - GitInteractiveRebaseEditorHandler editor = configureEditor(project, root, handler, commitListAware); - try { - GitCommandResult result = run(handler); - return editor.wasEditorCancelled() ? toCancelledResult(result) : result; - } - finally { - editor.close(); - } - } - - @Nonnull - private static GitCommandResult toCancelledResult(@Nonnull GitCommandResult result) { - int exitCode = result.getExitCode() == 0 ? 1 : result.getExitCode(); - return new GitCommandResult(false, exitCode, result.getErrorOutput(), result.getOutput(), result.getException()) { - @Override - public boolean cancelled() { - return true; - } - }; - } - - @Nonnull - protected GitInteractiveRebaseEditorHandler configureEditor(@Nonnull Project project, - @Nonnull VirtualFile root, - @Nonnull GitLineHandler handler, - boolean commitListAware) { - GitRebaseEditorService service = GitRebaseEditorService.getInstance(); - GitInteractiveRebaseEditorHandler editor = new GitInteractiveRebaseEditorHandler(service, project, root, handler); - if (!commitListAware) { - editor.setRebaseEditorShown(); - } - service.configureHandler(handler, editor.getHandlerNo()); - return editor; - } - - @Nonnull - private static GitCommandResult doLsRemote(@Nonnull final Project project, - @Nonnull final File workingDir, - @Nonnull final String remoteId, - @Nonnull final Collection authenticationUrls, - final String... additionalParameters) { - return run(() -> - { - GitLineHandler h = new GitLineHandler(project, workingDir, GitCommand.LS_REMOTE); - h.addParameters(additionalParameters); - h.addParameters(remoteId); - h.setUrls(authenticationUrls); - return h; - }); - } - - private static void addListeners(@Nonnull GitLineHandler handler, @Nonnull GitLineHandlerListener... listeners) { - addListeners(handler, Arrays.asList(listeners)); - } - - private static void addListeners(@Nonnull GitLineHandler handler, @Nonnull List listeners) { - for (GitLineHandlerListener listener : listeners) { - handler.addLineListener(listener); - } - } - - private static class OutputCollector { - final List errorOutput = new ArrayList<>(); - final List output = new ArrayList<>(); - - public void addOutput(String text) { - synchronized (output) { - output.add(text); - } - } - - public void addErrorOutput(String text) { - synchronized (errorOutput) { - errorOutput.add(text); - } - } - } - - @Nonnull - private static GitCommandResult run(@Nonnull Supplier handlerFactory) { - OutputCollector output; - final AtomicInteger exitCode = new AtomicInteger(); - final AtomicBoolean startFailed = new AtomicBoolean(); - final AtomicReference exception = new AtomicReference<>(); - - int authAttempt = 0; - boolean authFailed; - boolean success; - do { - output = new OutputCollector(); - exitCode.set(0); - startFailed.set(false); - exception.set(null); - - final OutputCollector tempCollector = output; - GitLineHandler handler = handlerFactory.get(); - handler.addLineListener(new GitLineHandlerListener() { - @Override - public void onLineAvailable(String line, Key outputType) { - if (looksLikeError(line)) { - tempCollector.addErrorOutput(line); - } - else { - tempCollector.addOutput(line); - } + public GitImpl() { + } + + /** + * Calls 'git init' on the specified directory. + */ + @Nonnull + @Override + public GitCommandResult init(@Nonnull Project project, @Nonnull VirtualFile root, @Nonnull GitLineHandlerListener... listeners) { + GitLineHandler h = new GitLineHandler(project, root, GitCommand.INIT); + for (GitLineHandlerListener listener : listeners) { + h.addLineListener(listener); + } + h.setSilent(false); + h.setStdoutSuppressed(false); + return run(h); + } + + /** + *

Queries Git for the unversioned files in the given paths.

+ *

Ignored files are left ignored, i. e. no information is returned about them (thus this method may also be used as a + * ignored files checker.

+ * + * @param files files that are to be checked for the unversioned files among them. + * Pass null to query the whole repository. + * @return Unversioned not ignored files from the given scope. + */ + @Nonnull + @Override + public Set untrackedFiles( + @Nonnull Project project, + @Nonnull VirtualFile root, + @Nullable Collection files + ) throws VcsException { + Set untrackedFiles = new HashSet<>(); + + if (files == null) { + untrackedFiles.addAll(untrackedFilesNoChunk(project, root, null)); + } + else { + for (List relativePaths : VcsFileUtil.chunkFiles(root, files)) { + untrackedFiles.addAll(untrackedFilesNoChunk(project, root, relativePaths)); + } + } + + return untrackedFiles; + } + + // relativePaths are guaranteed to fit into command line length limitations. + @Nonnull + @Override + public Collection untrackedFilesNoChunk( + @Nonnull Project project, + @Nonnull VirtualFile root, + @Nullable List relativePaths + ) throws VcsException { + Set untrackedFiles = new HashSet<>(); + GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LS_FILES); + h.setSilent(true); + h.addParameters("--exclude-standard", "--others", "-z"); + h.endOptions(); + if (relativePaths != null) { + h.addParameters(relativePaths); + } + + String output = h.run(); + if (StringUtil.isEmptyOrSpaces(output)) { + return untrackedFiles; + } + + for (String relPath : output.split("\u0000")) { + VirtualFile f = root.findFileByRelativePath(relPath); + if (f == null) { + // files was created on disk, but VirtualFile hasn't yet been created, + // when the GitChangeProvider has already been requested about changes. + LOG.info("VirtualFile for path [{}] is null", relPath); + } + else { + untrackedFiles.add(f); + } + } + + return untrackedFiles; + } + + @Nonnull + @Override + public GitCommandResult clone( + @Nonnull Project project, + @Nonnull File parentDirectory, + @Nonnull String url, + @Nullable String puttyKey, + @Nonnull String clonedDirectoryName, + @Nonnull GitLineHandlerListener... listeners + ) { + return run(() -> { + GitLineHandler handler = new GitLineHandler(project, parentDirectory, GitCommand.CLONE); + handler.setStdoutSuppressed(false); + handler.setUrl(url); + handler.addParameters("--progress"); + handler.addParameters(url); + handler.setPuttyKey(puttyKey); + handler.endOptions(); + handler.addParameters(clonedDirectoryName); + addListeners(handler, listeners); + return handler; + }); + } + + @Nonnull + @Override + public GitCommandResult config(@Nonnull GitRepository repository, String... params) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CONFIG); + h.addParameters(params); + return run(h); + } + + @Nonnull + @Override + public GitCommandResult diff(@Nonnull GitRepository repository, @Nonnull List parameters, @Nonnull String range) { + GitLineHandler diff = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.DIFF); + diff.addParameters(parameters); + diff.addParameters(range); + diff.setStdoutSuppressed(true); + diff.setStderrSuppressed(true); + diff.setSilent(true); + return run(diff); + } + + @Nonnull + @Override + public GitCommandResult checkAttr( + @Nonnull GitRepository repository, + @Nonnull Collection attributes, + @Nonnull Collection files + ) { + List> listOfPaths = VcsFileUtil.chunkFiles(repository.getRoot(), files); + return runAll(ContainerUtil.map( + listOfPaths, + (Function, Supplier>) relativePaths -> () -> { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECK_ATTR); + h.addParameters(new ArrayList<>(attributes)); + h.endOptions(); + h.addParameters(relativePaths); + return run(h); + } + )); + } + + @Nonnull + @Override + public GitCommandResult stashSave(@Nonnull GitRepository repository, @Nonnull String message) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.STASH); + h.addParameters("save"); + h.addParameters(message); + return run(h); + } + + @Nonnull + @Override + public GitCommandResult stashPop(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { + GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.STASH); + handler.addParameters("pop"); + addListeners(handler, listeners); + return run(handler); + } + + @Nonnull + @Override + public GitCommandResult merge( + @Nonnull GitRepository repository, + @Nonnull String branchToMerge, + @Nullable List additionalParams, + @Nonnull GitLineHandlerListener... listeners + ) { + GitLineHandler mergeHandler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.MERGE); + mergeHandler.setSilent(false); + mergeHandler.addParameters(branchToMerge); + if (additionalParams != null) { + mergeHandler.addParameters(additionalParams); + } + for (GitLineHandlerListener listener : listeners) { + mergeHandler.addLineListener(listener); + } + return run(mergeHandler); + } + + /** + * {@code git checkout <reference>}
+ * {@code git checkout -b <newBranch> <reference>} + */ + @Nonnull + @Override + public GitCommandResult checkout( + @Nonnull GitRepository repository, + @Nonnull String reference, + @Nullable String newBranch, + boolean force, + boolean detach, + @Nonnull GitLineHandlerListener... listeners + ) { + 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(detach ? reference + "^0" : reference); // we could use `--detach` here, but it is supported only since 1.7.5. + } + else { // checkout reference as new branch + h.addParameters("-b", newBranch, reference); + } + h.endOptions(); + for (GitLineHandlerListener listener : listeners) { + h.addLineListener(listener); + } + return run(h); + } + + /** + * {@code git checkout -b <branchName>} + */ + @Nonnull + @Override + public GitCommandResult checkoutNewBranch( + @Nonnull GitRepository repository, + @Nonnull String branchName, + @Nullable GitLineHandlerListener listener + ) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECKOUT.readLockingCommand()); + h.setSilent(false); + h.setStdoutSuppressed(false); + h.addParameters("-b"); + h.addParameters(branchName); + if (listener != null) { + h.addLineListener(listener); + } + return run(h); + } + + @Nonnull + @Override + public GitCommandResult createNewTag( + @Nonnull GitRepository repository, + @Nonnull String tagName, + @Nullable GitLineHandlerListener listener, + @Nonnull String reference + ) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.TAG); + h.setSilent(false); + h.addParameters(tagName); + if (!reference.isEmpty()) { + h.addParameters(reference); + } + if (listener != null) { + h.addLineListener(listener); + } + return run(h); + } + + /** + * {@code git branch -d } or {@code git branch -D } + */ + @Nonnull + @Override + public GitCommandResult branchDelete( + @Nonnull GitRepository repository, + @Nonnull String branchName, + boolean force, + @Nonnull GitLineHandlerListener... listeners + ) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); + h.setSilent(false); + h.setStdoutSuppressed(false); + h.addParameters(force ? "-D" : "-d"); + h.addParameters(branchName); + for (GitLineHandlerListener listener : listeners) { + h.addLineListener(listener); + } + return run(h); + } + + /** + * Get branches containing the commit. + * {@code git branch --contains } + */ + @Nonnull + @Override + public GitCommandResult branchContains(@Nonnull GitRepository repository, @Nonnull String commit) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); + h.addParameters("--contains", commit); + return run(h); + } + + @Nonnull + @Override + public GitCommandResult branchCreate(@Nonnull GitRepository repository, @Nonnull String branchName, @Nonnull String startPoint) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); + h.setStdoutSuppressed(false); + h.addParameters(branchName); + h.addParameters(startPoint); + return run(h); + } + + @Nonnull + @Override + public GitCommandResult renameBranch( + @Nonnull GitRepository repository, + @Nonnull String currentName, + @Nonnull String newName, + @Nonnull GitLineHandlerListener... listeners + ) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.BRANCH); + h.setStdoutSuppressed(false); + h.addParameters("-m", currentName, newName); + return run(h); + } + + @Nonnull + @Override + public GitCommandResult reset( + @Nonnull GitRepository repository, + @Nonnull GitResetMode mode, + @Nonnull String target, + @Nonnull GitLineHandlerListener... listeners + ) { + return reset(repository, mode.getArgument(), target, listeners); + } + + @Nonnull + @Override + public GitCommandResult resetMerge(@Nonnull GitRepository repository, @Nullable String revision) { + return reset(repository, "--merge", revision); + } + + @Nonnull + private static GitCommandResult reset( + @Nonnull GitRepository repository, + @Nonnull String argument, + @Nullable String target, + @Nonnull GitLineHandlerListener... listeners + ) { + GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.RESET); + handler.addParameters(argument); + if (target != null) { + handler.addParameters(target); + } + addListeners(handler, listeners); + return run(handler); + } + + /** + * Returns the last (tip) commit on the given branch.
+ * {@code git rev-list -1 } + */ + @Nonnull + @Override + public GitCommandResult tip(@Nonnull GitRepository repository, @Nonnull String branchName) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REV_LIST); + h.addParameters("-1"); + h.addParameters(branchName); + return run(h); + } + + @Nonnull + @Override + public GitCommandResult push( + @Nonnull GitRepository repository, + @Nonnull String remote, + @Nullable String url, + @Nullable String puttyKey, + @Nonnull String spec, + boolean updateTracking, + @Nonnull GitLineHandlerListener... listeners + ) { + return doPush(repository, remote, puttyKey, singleton(url), spec, false, updateTracking, false, null, listeners); + } + + @Nonnull + @Override + public GitCommandResult push( + @Nonnull GitRepository repository, + @Nonnull GitRemote remote, + @Nonnull String spec, + boolean force, + boolean updateTracking, + boolean skipHook, + @Nullable String tagMode, + GitLineHandlerListener... listeners + ) { + return doPush( + repository, + remote.getName(), + remote.getPuttyKeyFile(), + remote.getPushUrls(), + spec, + force, + updateTracking, + skipHook, + tagMode, + listeners + ); + } + + @Nonnull + private GitCommandResult doPush( + @Nonnull GitRepository repository, + @Nonnull String remoteName, + @Nullable String puttyKey, + @Nonnull Collection remoteUrls, + @Nonnull String spec, + boolean force, + boolean updateTracking, + boolean skipHook, + @Nullable String tagMode, + @Nonnull GitLineHandlerListener... listeners + ) { + return runCommand(() -> { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.PUSH); + h.setUrls(remoteUrls); + h.setPuttyKey(puttyKey); + h.setSilent(false); + h.setStdoutSuppressed(false); + addListeners(h, listeners); + h.addProgressParameter(); + h.addParameters("--porcelain"); + h.addParameters(remoteName); + h.addParameters(spec); + if (updateTracking) { + h.addParameters("--set-upstream"); + } + if (force) { + h.addParameters("--force"); + } + if (tagMode != null) { + h.addParameters(tagMode); + } + if (skipHook) { + h.addParameters("--no-verify"); + } + return h; + }); + } + + @Nonnull + @Override + public GitCommandResult show(@Nonnull GitRepository repository, @Nonnull String... params) { + GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.SHOW); + handler.addParameters(params); + return run(handler); + } + + @Override + @Nonnull + public GitCommandResult cherryPick( + @Nonnull GitRepository repository, + @Nonnull String hash, + boolean autoCommit, + @Nonnull GitLineHandlerListener... listeners + ) { + 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); + handler.setStdoutSuppressed(false); + return run(handler); + } + + @Nonnull + @Override + public GitCommandResult getUnmergedFiles(@Nonnull GitRepository repository) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.LS_FILES); + h.addParameters("--unmerged"); + h.setSilent(true); + return run(h); + } + + /** + * Fetch remote branch + * {@code git fetch } + */ + @Override + @Nonnull + public GitCommandResult fetch( + @Nonnull GitRepository repository, + @Nonnull GitRemote remote, + @Nonnull List listeners, + String... params + ) { + return runCommand(() -> { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.FETCH); + h.setSilent(false); + h.setStdoutSuppressed(false); + h.setUrls(remote.getUrls()); + h.setPuttyKey(remote.getPuttyKeyFile()); + h.addParameters(remote.getName()); + h.addParameters(params); + h.addProgressParameter(); + GitVcs vcs = GitVcs.getInstance(repository.getProject()); + if (vcs != null && GitVersionSpecialty.SUPPORTS_FETCH_PRUNE.existsIn(vcs.getVersion())) { + h.addParameters("--prune"); + } + addListeners(h, listeners); + return h; + }); + } + + @Nonnull + @Override + public GitCommandResult addRemote(@Nonnull GitRepository repository, @Nonnull String name, @Nonnull String url) { + GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REMOTE); + h.addParameters("add", name, url); + return run(h); + } + + @Nonnull + @Override + public GitCommandResult lsRemote(@Nonnull Project project, @Nonnull File workingDir, @Nonnull String url) { + return doLsRemote(project, workingDir, url, singleton(url)); + } + + @Nonnull + @Override + public GitCommandResult lsRemote( + @Nonnull Project project, + @Nonnull VirtualFile workingDir, + @Nonnull GitRemote remote, + String... additionalParameters + ) { + return doLsRemote(project, VirtualFileUtil.virtualToIoFile(workingDir), remote.getName(), remote.getUrls(), additionalParameters); + } + + @Nonnull + @Override + public GitCommandResult remotePrune(@Nonnull GitRepository repository, @Nonnull GitRemote remote) { + return run(() -> { + GitLineHandler h = + new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REMOTE.writeLockingCommand()); + h.setStdoutSuppressed(false); + h.addParameters("prune"); + h.addParameters(remote.getName()); + h.setUrls(remote.getUrls()); + return h; + }); + } + + @Nonnull + @Override + public GitCommandResult rebase( + @Nonnull GitRepository repository, + @Nonnull GitRebaseParams parameters, + @Nonnull GitLineHandlerListener... listeners + ) { + Project project = repository.getProject(); + VirtualFile root = repository.getRoot(); + GitLineHandler handler = new GitLineHandler(project, root, GitCommand.REBASE); + handler.addParameters(parameters.asCommandLineArguments()); + addListeners(handler, listeners); + return parameters.isInteractive() ? runWithEditor(project, root, handler, true) : run(handler); + } + + @Nonnull + @Override + public GitCommandResult rebaseAbort(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { + GitLineHandler handler = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.REBASE); + handler.addParameters("--abort"); + addListeners(handler, listeners); + return run(handler); + } + + @Nonnull + @Override + public GitCommandResult rebaseContinue(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { + return rebaseResume(repository, GitRebaseResumeMode.CONTINUE, listeners); + } + + @Nonnull + @Override + public GitCommandResult rebaseSkip(@Nonnull GitRepository repository, @Nonnull GitLineHandlerListener... listeners) { + return rebaseResume(repository, GitRebaseResumeMode.SKIP, listeners); + } + + @Nonnull + private GitCommandResult rebaseResume( + @Nonnull GitRepository repository, + @Nonnull GitRebaseResumeMode rebaseMode, + @Nonnull GitLineHandlerListener[] listeners + ) { + Project project = repository.getProject(); + VirtualFile root = repository.getRoot(); + GitLineHandler handler = new GitLineHandler(project, root, GitCommand.REBASE); + handler.addParameters(rebaseMode.asCommandLineArgument()); + addListeners(handler, listeners); + return runWithEditor(project, root, handler, false); + } + + @Nonnull + private GitCommandResult runWithEditor( + @Nonnull Project project, + @Nonnull VirtualFile root, + @Nonnull GitLineHandler handler, + boolean commitListAware + ) { + GitInteractiveRebaseEditorHandler editor = configureEditor(project, root, handler, commitListAware); + try { + GitCommandResult result = run(handler); + return editor.wasEditorCancelled() ? toCancelledResult(result) : result; + } + finally { + editor.close(); + } + } + + @Nonnull + private static GitCommandResult toCancelledResult(@Nonnull GitCommandResult result) { + int exitCode = result.getExitCode() == 0 ? 1 : result.getExitCode(); + return new GitCommandResult(false, exitCode, result.getErrorOutput(), result.getOutput(), result.getException()) { + @Override + public boolean cancelled() { + return true; + } + }; + } + + @Nonnull + protected GitInteractiveRebaseEditorHandler configureEditor( + @Nonnull Project project, + @Nonnull VirtualFile root, + @Nonnull GitLineHandler handler, + boolean commitListAware + ) { + GitRebaseEditorService service = GitRebaseEditorService.getInstance(); + GitInteractiveRebaseEditorHandler editor = new GitInteractiveRebaseEditorHandler(service, project, root, handler); + if (!commitListAware) { + editor.setRebaseEditorShown(); + } + service.configureHandler(handler, editor.getHandlerNo()); + return editor; + } + + @Nonnull + private static GitCommandResult doLsRemote( + @Nonnull Project project, + @Nonnull File workingDir, + @Nonnull String remoteId, + @Nonnull Collection authenticationUrls, + String... additionalParameters + ) { + return run(() -> { + GitLineHandler h = new GitLineHandler(project, workingDir, GitCommand.LS_REMOTE); + h.addParameters(additionalParameters); + h.addParameters(remoteId); + h.setUrls(authenticationUrls); + return h; + }); + } + + private static void addListeners(@Nonnull GitLineHandler handler, @Nonnull GitLineHandlerListener... listeners) { + addListeners(handler, Arrays.asList(listeners)); + } + + private static void addListeners(@Nonnull GitLineHandler handler, @Nonnull List listeners) { + for (GitLineHandlerListener listener : listeners) { + handler.addLineListener(listener); + } + } + + private static class OutputCollector { + final List errorOutput = new ArrayList<>(); + final List output = new ArrayList<>(); + + public void addOutput(String text) { + synchronized (output) { + output.add(text); + } } - @Override - public void processTerminated(int code) { - exitCode.set(code); + public void addErrorOutput(String text) { + synchronized (errorOutput) { + errorOutput.add(text); + } } + } - @Override - public void startFailed(Throwable t) { - startFailed.set(true); - tempCollector.addErrorOutput("Failed to start Git process"); - exception.set(t); + @Nonnull + private static GitCommandResult run(@Nonnull Supplier handlerFactory) { + OutputCollector output; + final AtomicInteger exitCode = new AtomicInteger(); + final AtomicBoolean startFailed = new AtomicBoolean(); + final AtomicReference exception = new AtomicReference<>(); + + int authAttempt = 0; + boolean authFailed; + boolean success; + do { + output = new OutputCollector(); + exitCode.set(0); + startFailed.set(false); + exception.set(null); + + final OutputCollector tempCollector = output; + GitLineHandler handler = handlerFactory.get(); + handler.addLineListener(new GitLineHandlerListener() { + @Override + public void onLineAvailable(String line, Key outputType) { + if (looksLikeError(line)) { + tempCollector.addErrorOutput(line); + } + else { + tempCollector.addOutput(line); + } + } + + @Override + public void processTerminated(int code) { + exitCode.set(code); + } + + @Override + public void startFailed(Throwable t) { + startFailed.set(true); + tempCollector.addErrorOutput("Failed to start Git process"); + exception.set(t); + } + }); + + handler.runInCurrentThread(null); + authFailed = handler.hasHttpAuthFailed(); + success = !startFailed.get() && (handler.isIgnoredErrorCode(exitCode.get()) || exitCode.get() == 0); } - }); - - handler.runInCurrentThread(null); - authFailed = handler.hasHttpAuthFailed(); - success = !startFailed.get() && (handler.isIgnoredErrorCode(exitCode.get()) || exitCode.get() == 0); - } - while (authFailed && authAttempt++ < 2); - return new GitCommandResult(success, exitCode.get(), output.errorOutput, output.output, null); - } - - /** - * Runs the given {@link GitLineHandler} in the current thread and returns the {@link GitCommandResult}. - */ - @Nonnull - private static GitCommandResult run(@Nonnull GitLineHandler handler) { - return run(() -> handler); - } - - @Override - @Nonnull - public GitCommandResult runCommand(@Nonnull Supplier handlerConstructor) { - return run(handlerConstructor); - } - - @Nonnull - @Override - public GitCommandResult runCommand(@Nonnull final GitLineHandler handler) { - return runCommand(() -> handler); - } - - @Nonnull - private static GitCommandResult runAll(@Nonnull List> commands) { - if (commands.isEmpty()) { - LOG.error("List of commands should not be empty", new Exception()); - return GitCommandResult.error("Internal error"); - } - GitCommandResult compoundResult = null; - for (Supplier command : commands) { - compoundResult = GitCommandResult.merge(compoundResult, command.get()); - } - return ObjectUtil.assertNotNull(compoundResult); - } - - private static boolean looksLikeError(@Nonnull final String text) { - return ContainerUtil.exists(ERROR_INDICATORS, indicator -> StringUtil.startsWithIgnoreCase(text.trim(), indicator)); - } - - // could be upper-cased, so should check case-insensitively - public static final String[] ERROR_INDICATORS = { - "error:", - "remote: error", - "fatal:", - "Cannot", - "Could not", - "Interactive rebase already started", - "refusing to pull", - "cannot rebase:", - "conflict", - "unable" - }; + while (authFailed && authAttempt++ < 2); + return new GitCommandResult(success, exitCode.get(), output.errorOutput, output.output, null); + } + + /** + * Runs the given {@link GitLineHandler} in the current thread and returns the {@link GitCommandResult}. + */ + @Nonnull + private static GitCommandResult run(@Nonnull GitLineHandler handler) { + return run(() -> handler); + } + + @Override + @Nonnull + public GitCommandResult runCommand(@Nonnull Supplier handlerConstructor) { + return run(handlerConstructor); + } + + @Nonnull + @Override + public GitCommandResult runCommand(@Nonnull GitLineHandler handler) { + return runCommand(() -> handler); + } + + @Nonnull + private static GitCommandResult runAll(@Nonnull List> commands) { + if (commands.isEmpty()) { + LOG.error("List of commands should not be empty", new Exception()); + return GitCommandResult.error("Internal error"); + } + GitCommandResult compoundResult = null; + for (Supplier command : commands) { + compoundResult = GitCommandResult.merge(compoundResult, command.get()); + } + return ObjectUtil.assertNotNull(compoundResult); + } + + private static boolean looksLikeError(@Nonnull String text) { + return ContainerUtil.exists(ERROR_INDICATORS, indicator -> StringUtil.startsWithIgnoreCase(text.trim(), indicator)); + } + + // could be upper-cased, so should check case-insensitively + public static final String[] ERROR_INDICATORS = { + "error:", + "remote: error", + "fatal:", + "Cannot", + "Could not", + "Interactive rebase already started", + "refusing to pull", + "cannot rebase:", + "conflict", + "unable" + }; } diff --git a/plugin/src/main/java/git4idea/commands/GitLineHandler.java b/plugin/src/main/java/git4idea/commands/GitLineHandler.java index 20ad60d..9374870 100644 --- a/plugin/src/main/java/git4idea/commands/GitLineHandler.java +++ b/plugin/src/main/java/git4idea/commands/GitLineHandler.java @@ -22,8 +22,8 @@ import consulo.util.lang.StringUtil; import consulo.versionControlSystem.util.LineHandlerHelper; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; + import java.io.File; import java.util.Iterator; @@ -31,137 +31,140 @@ * The handler that is based on per-line processing of the text. */ public class GitLineHandler extends GitTextHandler { - /** - * the partial line from stdout stream - */ - private final StringBuilder myStdoutLine = new StringBuilder(); - /** - * the partial line from stderr stream - */ - private final StringBuilder myStderrLine = new StringBuilder(); - /** - * Line listeners - */ - private final EventDispatcher myLineListeners = EventDispatcher.create(GitLineHandlerListener.class); - - /** - * A constructor - * - * @param project a project - * @param directory a process directory - * @param command a command to execute - */ - @SuppressWarnings({"WeakerAccess"}) - public GitLineHandler(@Nonnull Project project, @Nonnull File directory, @Nonnull GitCommand command) { - super(project, directory, command); - } - - /** - * A constructor - * - * @param project a project - * @param vcsRoot a process directory - * @param command a command to execute - */ - public GitLineHandler(@Nonnull final Project project, @Nonnull final VirtualFile vcsRoot, @Nonnull final GitCommand command) { - super(project, vcsRoot, command); - } + /** + * the partial line from stdout stream + */ + private final StringBuilder myStdoutLine = new StringBuilder(); + /** + * the partial line from stderr stream + */ + private final StringBuilder myStderrLine = new StringBuilder(); + /** + * Line listeners + */ + private final EventDispatcher myLineListeners = EventDispatcher.create(GitLineHandlerListener.class); - /** - * {@inheritDoc} - */ - protected void processTerminated(final int exitCode) { - // force newline - if (myStdoutLine.length() != 0) { - onTextAvailable("\n\r", ProcessOutputTypes.STDOUT); + /** + * A constructor + * + * @param project a project + * @param directory a process directory + * @param command a command to execute + */ + @SuppressWarnings({"WeakerAccess"}) + public GitLineHandler(@Nonnull Project project, @Nonnull File directory, @Nonnull GitCommand command) { + super(project, directory, command); } - else if (!isStderrSuppressed() && myStderrLine.length() != 0) { - onTextAvailable("\n\r", ProcessOutputTypes.STDERR); - } - } - - /** - * Add listener - * - * @param listener a listener to add - */ - public void addLineListener(GitLineHandlerListener listener) { - super.addListener(listener); - myLineListeners.addListener(listener); - } + /** + * A constructor + * + * @param project a project + * @param vcsRoot a process directory + * @param command a command to execute + */ + public GitLineHandler(@Nonnull Project project, @Nonnull VirtualFile vcsRoot, @Nonnull GitCommand command) { + super(project, vcsRoot, command); + } - /** - * {@inheritDoc} - */ - protected void onTextAvailable(final String text, final Key outputType) { - Iterator lines = LineHandlerHelper.splitText(text).iterator(); - if (ProcessOutputTypes.STDOUT == outputType) { - notifyLines(outputType, lines, myStdoutLine); + /** + * {@inheritDoc} + */ + @Override + protected void processTerminated(int exitCode) { + // force newline + if (myStdoutLine.length() != 0) { + onTextAvailable("\n\r", ProcessOutputTypes.STDOUT); + } + else if (!isStderrSuppressed() && myStderrLine.length() != 0) { + onTextAvailable("\n\r", ProcessOutputTypes.STDERR); + } } - else if (ProcessOutputTypes.STDERR == outputType) { - notifyLines(outputType, lines, myStderrLine); + + /** + * Add listener + * + * @param listener a listener to add + */ + public void addLineListener(GitLineHandlerListener listener) { + super.addListener(listener); + myLineListeners.addListener(listener); } - } - /** - * Notify listeners for each complete line. Note that in the case of stderr, the last line is saved. - * - * @param outputType output type - * @param lines line iterator - * @param lineBuilder a line builder - */ - private void notifyLines(final Key outputType, final Iterator lines, final StringBuilder lineBuilder) { - if (!lines.hasNext()) return; - if (lineBuilder.length() > 0) { - lineBuilder.append(lines.next()); - if (lines.hasNext()) { - // line is complete - final String line = lineBuilder.toString(); - notifyLine(line, outputType); - lineBuilder.setLength(0); - } + /** + * {@inheritDoc} + */ + @Override + protected void onTextAvailable(String text, Key outputType) { + Iterator lines = LineHandlerHelper.splitText(text).iterator(); + if (ProcessOutputTypes.STDOUT == outputType) { + notifyLines(outputType, lines, myStdoutLine); + } + else if (ProcessOutputTypes.STDERR == outputType) { + notifyLines(outputType, lines, myStderrLine); + } } - while (true) { - String line = null; - if (lines.hasNext()) { - line = lines.next(); - } - if (lines.hasNext()) { - notifyLine(line, outputType); - } - else { - if (line != null && line.length() > 0) { - lineBuilder.append(line); + /** + * Notify listeners for each complete line. Note that in the case of stderr, the last line is saved. + * + * @param outputType output type + * @param lines line iterator + * @param lineBuilder a line builder + */ + private void notifyLines(Key outputType, Iterator lines, StringBuilder lineBuilder) { + if (!lines.hasNext()) { + return; + } + if (lineBuilder.length() > 0) { + lineBuilder.append(lines.next()); + if (lines.hasNext()) { + // line is complete + String line = lineBuilder.toString(); + notifyLine(line, outputType); + lineBuilder.setLength(0); + } + } + while (true) { + String line = null; + if (lines.hasNext()) { + line = lines.next(); + } + + if (lines.hasNext()) { + notifyLine(line, outputType); + } + else { + if (line != null && line.length() > 0) { + lineBuilder.append(line); + } + break; + } } - break; - } } - } - /** - * Notify single line - * - * @param line a line to notify - * @param outputType output type - */ - private void notifyLine(final String line, final Key outputType) { - String trimmed = LineHandlerHelper.trimLineSeparator(line); - // if line ends with return, then it is a progress line, ignore it - if (myVcs != null && !"\r".equals(line.substring(trimmed.length()))) { - if (outputType == ProcessOutputTypes.STDOUT && !isStdoutSuppressed() && !mySilent && !StringUtil.isEmptyOrSpaces(line)) { - myVcs.showMessages(trimmed); - LOG.info(line.trim()); - } - else if (outputType == ProcessOutputTypes.STDERR && !isStderrSuppressed() && !mySilent && !StringUtil.isEmptyOrSpaces(line)) { - myVcs.showErrorMessages(trimmed); - LOG.info(line.trim()); - } - else { - LOG.debug(line.trim()); - } + /** + * Notify single line + * + * @param line a line to notify + * @param outputType output type + */ + private void notifyLine(String line, Key outputType) { + String trimmed = LineHandlerHelper.trimLineSeparator(line); + // if line ends with return, then it is a progress line, ignore it + if (myVcs != null && !"\r".equals(line.substring(trimmed.length()))) { + if (outputType == ProcessOutputTypes.STDOUT && !isStdoutSuppressed() && !mySilent && !StringUtil.isEmptyOrSpaces(line)) { + myVcs.showMessages(trimmed); + LOG.info(line.trim()); + } + else if (outputType == ProcessOutputTypes.STDERR && !isStderrSuppressed() && !mySilent && !StringUtil.isEmptyOrSpaces(line)) { + myVcs.showErrorMessages(trimmed); + LOG.info(line.trim()); + } + else { + LOG.debug(line.trim()); + } + } + myLineListeners.getMulticaster().onLineAvailable(trimmed, outputType); } - myLineListeners.getMulticaster().onLineAvailable(trimmed, outputType); - } } diff --git a/plugin/src/main/java/git4idea/commands/GitSimpleHandler.java b/plugin/src/main/java/git4idea/commands/GitSimpleHandler.java index fbd1bab..b5da3d1 100644 --- a/plugin/src/main/java/git4idea/commands/GitSimpleHandler.java +++ b/plugin/src/main/java/git4idea/commands/GitSimpleHandler.java @@ -73,7 +73,7 @@ public GitSimpleHandler(@Nonnull Project project, @Nonnull File directory, @Nonn * @param command a command to execute */ @SuppressWarnings({"WeakerAccess"}) - public GitSimpleHandler(@Nonnull final Project project, @Nonnull final VirtualFile directory, @Nonnull final GitCommand command) { + public GitSimpleHandler(@Nonnull Project project, @Nonnull VirtualFile directory, @Nonnull GitCommand command) { super(project, directory, command); } @@ -81,7 +81,7 @@ public GitSimpleHandler(@Nonnull final Project project, @Nonnull final VirtualFi * {@inheritDoc} */ @Override - protected void processTerminated(final int exitCode) { + protected void processTerminated(int exitCode) { if (myVcs == null) { return; } @@ -123,10 +123,10 @@ public void unsilence() { * {@inheritDoc} */ @Override - protected void onTextAvailable(final String text, final Key outputType) { - final StringBuilder entire; - final StringBuilder lineRest; - final boolean suppressed; + protected void onTextAvailable(String text, Key outputType) { + StringBuilder entire; + StringBuilder lineRest; + boolean suppressed; if (ProcessOutputTypes.STDOUT == outputType) { entire = myStdout; lineRest = myStdoutLine; @@ -217,7 +217,7 @@ public String run() throws VcsException { final String[] result = new String[1]; addListener(new GitHandlerListener() { @Override - public void processTerminated(final int exitCode) { + public void processTerminated(int exitCode) { try { if (exitCode == 0 || isIgnoredErrorCode(exitCode)) { result[0] = getStdout(); @@ -239,7 +239,7 @@ public void processTerminated(final int exitCode) { } @Override - public void startFailed(final Throwable exception) { + public void startFailed(Throwable exception) { ex[0] = new VcsException( "Process failed to start (" + myCommandLine.getCommandLineString() + "): " + exception.toString(), exception diff --git a/plugin/src/main/java/git4idea/commands/GitTask.java b/plugin/src/main/java/git4idea/commands/GitTask.java index 858e9c9..bccac17 100644 --- a/plugin/src/main/java/git4idea/commands/GitTask.java +++ b/plugin/src/main/java/git4idea/commands/GitTask.java @@ -22,7 +22,6 @@ import consulo.disposer.Disposable; import consulo.disposer.Disposer; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.util.dataholder.Key; @@ -31,6 +30,8 @@ import git4idea.GitVcs; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Timer; import java.util.TimerTask; @@ -54,7 +55,7 @@ * @author Kirill Likhodedov */ public class GitTask { - private static final Logger LOG = Logger.getInstance(GitTask.class); + private static final Logger LOG = LoggerFactory.getLogger(GitTask.class); private final Project myProject; private final GitHandler myHandler; @@ -182,7 +183,7 @@ public void onCancel() { } } catch (InterruptedException e) { - LOG.info(e); + LOG.info("Interrupted", e); } } } @@ -301,7 +302,7 @@ public final void run(@Nonnull ProgressIndicator indicator) { @RequiredUIAccess public final void runAlone() { - Application application = Application.get(); + Application application = ((Project) getProject()).getApplication(); if (application.isDispatchThread()) { application.executeOnPooledThread((Runnable) this::justRun); } diff --git a/plugin/src/main/java/git4idea/commands/GitTextHandler.java b/plugin/src/main/java/git4idea/commands/GitTextHandler.java index 0451c68..169f7e1 100644 --- a/plugin/src/main/java/git4idea/commands/GitTextHandler.java +++ b/plugin/src/main/java/git4idea/commands/GitTextHandler.java @@ -25,113 +25,113 @@ import consulo.project.Project; import consulo.util.dataholder.Key; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.io.File; /** * The handler for git commands with text outputs */ public abstract class GitTextHandler extends GitHandler { - // note that access is safe because it accessed in unsynchronized block only after process is started, and it does not change after that - @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) - private ProcessHandler myHandler; - private volatile boolean myIsDestroyed; - private final Object myProcessStateLock = new Object(); - - protected GitTextHandler(@Nonnull Project project, @Nonnull File directory, @Nonnull GitCommand command) { - super(project, directory, command); - } + // note that access is safe because it accessed in unsynchronized block only after process is started, and it does not change after that + @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) + private ProcessHandler myHandler; + private volatile boolean myIsDestroyed; + private final Object myProcessStateLock = new Object(); - protected GitTextHandler(final Project project, final VirtualFile vcsRoot, final GitCommand command) { - super(project, vcsRoot, command); - } - - @Nullable - @Override - protected Process startProcess() throws ExecutionException { - synchronized (myProcessStateLock) { - if (myIsDestroyed) { - return null; - } - final ProcessHandler processHandler = createProcess(myCommandLine); - myHandler = processHandler; - return ((NativeProcessHandler) myHandler).getProcess(); + protected GitTextHandler(@Nonnull Project project, @Nonnull File directory, @Nonnull GitCommand command) { + super(project, directory, command); } - } - @Override - protected void startHandlingStreams() { - if (myHandler == null) { - return; + protected GitTextHandler(Project project, VirtualFile vcsRoot, GitCommand command) { + super(project, vcsRoot, command); } - myHandler.addProcessListener(new ProcessListener() { - @Override - public void startNotified(final ProcessEvent event) { - // do nothing - } - @Override - public void processTerminated(final ProcessEvent event) { - final int exitCode = event.getExitCode(); - try { - setExitCode(exitCode); - cleanupEnv(); - GitTextHandler.this.processTerminated(exitCode); + @Nullable + @Override + protected Process startProcess() throws ExecutionException { + synchronized (myProcessStateLock) { + if (myIsDestroyed) { + return null; + } + ProcessHandler processHandler = createProcess(myCommandLine); + myHandler = processHandler; + return ((NativeProcessHandler) myHandler).getProcess(); } - finally { - listeners().processTerminated(exitCode); + } + + @Override + protected void startHandlingStreams() { + if (myHandler == null) { + return; } - } + myHandler.addProcessListener(new ProcessListener() { + @Override + public void startNotified(ProcessEvent event) { + // do nothing + } - @Override - public void processWillTerminate(final ProcessEvent event, final boolean willBeDestroyed) { - // do nothing - } + @Override + public void processTerminated(ProcessEvent event) { + int exitCode = event.getExitCode(); + try { + setExitCode(exitCode); + cleanupEnv(); + GitTextHandler.this.processTerminated(exitCode); + } + finally { + listeners().processTerminated(exitCode); + } + } - @Override - public void onTextAvailable(final ProcessEvent event, final Key outputType) { - GitTextHandler.this.onTextAvailable(event.getText(), outputType); - } - }); - myHandler.startNotify(); - } + @Override + public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) { + // do nothing + } - /** - * Notification for handler to handle process exit event - * - * @param exitCode a exit code. - */ - protected abstract void processTerminated(int exitCode); + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + GitTextHandler.this.onTextAvailable(event.getText(), outputType); + } + }); + myHandler.startNotify(); + } + + /** + * Notification for handler to handle process exit event + * + * @param exitCode a exit code. + */ + protected abstract void processTerminated(int exitCode); - /** - * This method is invoked when some text is available - * - * @param text an available text - * @param outputType output type - */ - protected abstract void onTextAvailable(final String text, final Key outputType); + /** + * This method is invoked when some text is available + * + * @param text an available text + * @param outputType output type + */ + protected abstract void onTextAvailable(String text, Key outputType); - @Override - public void destroyProcess() { - synchronized (myProcessStateLock) { - myIsDestroyed = true; - if (myHandler != null) { - myHandler.destroyProcess(); - } + @Override + public void destroyProcess() { + synchronized (myProcessStateLock) { + myIsDestroyed = true; + if (myHandler != null) { + myHandler.destroyProcess(); + } + } } - } - @Override - protected void waitForProcess() { - if (myHandler != null) { - myHandler.waitFor(); + @Override + protected void waitForProcess() { + if (myHandler != null) { + myHandler.waitFor(); + } } - } - public ProcessHandler createProcess(@Nonnull GeneralCommandLine commandLine) throws ExecutionException { - commandLine.setCharset(getCharset()); - return ProcessHandlerBuilder.create(commandLine).killable().blockingReader().build(); - } + public ProcessHandler createProcess(@Nonnull GeneralCommandLine commandLine) throws ExecutionException { + commandLine.setCharset(getCharset()); + return ProcessHandlerBuilder.create(commandLine).killable().blockingReader().build(); + } } diff --git a/plugin/src/main/java/git4idea/config/GitExecutableDetector.java b/plugin/src/main/java/git4idea/config/GitExecutableDetector.java index d15ef2a..1da9de5 100644 --- a/plugin/src/main/java/git4idea/config/GitExecutableDetector.java +++ b/plugin/src/main/java/git4idea/config/GitExecutableDetector.java @@ -15,7 +15,6 @@ */ package git4idea.config; -import consulo.logging.Logger; import consulo.platform.Platform; import consulo.process.ExecutionException; import consulo.process.cmd.GeneralCommandLine; @@ -26,6 +25,8 @@ import consulo.util.lang.StringUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.util.*; @@ -39,7 +40,7 @@ * @author Kirill Likhodedov */ public class GitExecutableDetector { - private static final Logger LOG = Logger.getInstance(GitExecutableDetector.class); + private static final Logger LOG = LoggerFactory.getLogger(GitExecutableDetector.class); private static final String[] UNIX_PATHS = { "/usr/local/bin", "/usr/bin", @@ -127,7 +128,7 @@ private static boolean looksLikeGit(@Nonnull String path) { @Nullable private static String checkProgramFiles() { - final String[] PROGRAM_FILES = { + String[] PROGRAM_FILES = { "Program Files", "Program Files (x86)" }; @@ -157,7 +158,7 @@ private static String checkProgramFiles() { @Nullable private static String checkCygwin() { - final String[] OTHER_WINDOWS_PATHS = {FileUtil.toSystemDependentName("cygwin/bin/git.exe")}; + String[] OTHER_WINDOWS_PATHS = {FileUtil.toSystemDependentName("cygwin/bin/git.exe")}; for (String otherPath : OTHER_WINDOWS_PATHS) { File file = new File(WIN_ROOT, otherPath); if (file.exists()) { @@ -181,7 +182,7 @@ private static String checkDistributive(@Nullable File gitDir) { return null; } - final String[] binDirs = { + String[] binDirs = { "cmd", "bin" }; @@ -249,7 +250,7 @@ else if (name2.equals("git")) { return -1; } - final Pattern GIT_WITH_VERSION = Pattern.compile("^git[ _]*([\\d\\.]*).*$"); + Pattern GIT_WITH_VERSION = Pattern.compile("^git[ _]*([\\d\\.]*).*$"); Matcher m1 = GIT_WITH_VERSION.matcher(name1); Matcher m2 = GIT_WITH_VERSION.matcher(name2); if (m1.matches() && m2.matches()) { @@ -284,7 +285,7 @@ private static GitVersion parseGitVersion(@Nullable String name) { if (name == null) { return null; } - final Pattern VERSION = Pattern.compile("(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:\\.(\\d+))?.*"); + Pattern VERSION = Pattern.compile("(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:\\.(\\d+))?.*"); Matcher m = VERSION.matcher(name); if (!m.matches()) { return null; @@ -294,7 +295,7 @@ private static GitVersion parseGitVersion(@Nullable String name) { return new GitVersion(major, parseOrNull(m.group(2)), parseOrNull(m.group(3)), parseOrNull(m.group(4))); } catch (NumberFormatException e) { - LOG.info("Unexpected NFE when parsing [" + name + "]", e); + LOG.info("Unexpected NFE when parsing [{}]", name, e); return null; } } diff --git a/plugin/src/main/java/git4idea/config/GitVersion.java b/plugin/src/main/java/git4idea/config/GitVersion.java index 730fd27..fd20eeb 100644 --- a/plugin/src/main/java/git4idea/config/GitVersion.java +++ b/plugin/src/main/java/git4idea/config/GitVersion.java @@ -19,7 +19,6 @@ import consulo.application.progress.ProgressManager; import consulo.component.ProcessCanceledException; import consulo.execution.ExecutableValidator; -import consulo.logging.Logger; import consulo.platform.Platform; import consulo.process.ExecutionException; import consulo.process.cmd.GeneralCommandLine; @@ -30,6 +29,8 @@ import consulo.util.lang.StringUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.text.ParseException; import java.util.Objects; @@ -78,7 +79,7 @@ public enum Type { private static final Pattern FORMAT = Pattern.compile("git version (\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(.*)", Pattern.CASE_INSENSITIVE); - private static final Logger LOG = Logger.getInstance(GitVersion.class); + private static final Logger LOG = LoggerFactory.getLogger(GitVersion.class); private final int myMajor; private final int myMinor; @@ -165,11 +166,11 @@ public static GitVersion identifyVersion(@Nonnull String gitExecutable, @Nullabl throw new TimeoutException("Couldn't identify the version of Git - stopped by timeout."); } else if (result.isCancelled()) { - LOG.info("Cancelled by user. exitCode=" + result.getExitCode()); + LOG.info("Cancelled by user. exitCode={}", result.getExitCode()); throw new ProcessCanceledException(); } else if (result.getExitCode() != 0 || !result.getStderr().isEmpty()) { - LOG.info("getVersion exitCode=" + result.getExitCode() + " errors: " + result.getStderr()); + LOG.info("getVersion exitCode={} errors: {}", result.getExitCode(), result.getStderr()); // anyway trying to parse try { parse(result.getStdout()); diff --git a/plugin/src/main/java/git4idea/crlf/GitCrlfProblemsDetector.java b/plugin/src/main/java/git4idea/crlf/GitCrlfProblemsDetector.java index 806d558..ada8831 100644 --- a/plugin/src/main/java/git4idea/crlf/GitCrlfProblemsDetector.java +++ b/plugin/src/main/java/git4idea/crlf/GitCrlfProblemsDetector.java @@ -16,7 +16,6 @@ package git4idea.crlf; import consulo.application.progress.ProgressIndicatorProvider; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.io.FileUtil; import consulo.virtualFileSystem.VirtualFile; @@ -29,6 +28,8 @@ import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; @@ -50,8 +51,7 @@ * @author Kirill Likhodedov */ public class GitCrlfProblemsDetector { - - private static final Logger LOG = Logger.getInstance(GitCrlfProblemsDetector.class); + private static final Logger LOG = LoggerFactory.getLogger(GitCrlfProblemsDetector.class); private static final String CRLF = "\r\n"; @Nonnull @@ -101,13 +101,13 @@ private Map> findFilesWithoutAttrs(Map findFilesWithoutAttrs(@Nonnull VirtualFile root, @Nonnull Collection files) { GitRepository repository = GitRepositoryManager.getInstance(myProject).getRepositoryForRoot(root); if (repository == null) { - LOG.warn("Repository is null for " + root); + LOG.warn("Repository is null for {}", root); return Collections.emptyList(); } Collection interestingAttributes = Arrays.asList(GitAttribute.TEXT.getName(), GitAttribute.CRLF.getName()); GitCommandResult result = myGit.checkAttr(repository, interestingAttributes, files); if (!result.success()) { - LOG.warn(String.format("Couldn't git check-attr. Attributes: %s, files: %s", interestingAttributes, files)); + LOG.warn("Couldn't git check-attr. Attributes: {}, files: {}", interestingAttributes, files); return Collections.emptyList(); } GitCheckAttrParser parser = GitCheckAttrParser.parse(result.getOutput()); @@ -172,7 +172,7 @@ private Collection getRootsWithIncorrectAutoCrlf(@Nonnull Map getRemotelyChanged(VirtualFile vcsRoot, Collection, VcsBaseRevisionAdviser { - private static final Logger log = Logger.getInstance(GitHistoryProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(GitHistoryProvider.class); @Nonnull private final Project myProject; @@ -72,7 +73,7 @@ public GitHistoryProvider(@Nonnull Project project) { @Override public VcsDependentHistoryComponents getUICustomization( - final VcsHistorySession session, + VcsHistorySession session, JComponent forShortcutRegistration ) { return VcsDependentHistoryComponents.createOnlyColumns(new ColumnInfo[0]); @@ -120,7 +121,7 @@ public VcsAbstractHistorySession createFromCachedData( @Nullable @Override - public VcsHistorySession createSessionFor(final FilePath filePath) throws VcsException { + public VcsHistorySession createSessionFor(FilePath filePath) throws VcsException { List revisions = null; try { revisions = GitHistoryUtils.history(myProject, filePath); @@ -144,9 +145,7 @@ protected VcsRevisionNumber calcCurrentRevisionNumber() { } catch (VcsException e) { // likely the file is not under VCS anymore. - if (log.isDebugEnabled()) { - log.debug("Unable to retrieve the current revision number", e); - } + LOG.debug("Unable to retrieve the current revision number", e); return null; } } @@ -167,7 +166,7 @@ public VcsHistorySession copy() { public boolean getBaseVersionContent( FilePath filePath, Predicate processor, - final String beforeVersionId, + String beforeVersionId, List warnings ) throws VcsException { @@ -175,14 +174,14 @@ public boolean getBaseVersionContent( return false; } // apply if base revision id matches revision - final VirtualFile root = GitUtil.getGitRoot(filePath); + VirtualFile root = GitUtil.getGitRoot(filePath); - final SHAHash shaHash = GitChangeUtils.commitExists(myProject, root, beforeVersionId, null, "HEAD"); + 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() + 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() + "'"); @@ -191,8 +190,9 @@ public boolean getBaseVersionContent( } @Override - public void reportAppendableHistory(final FilePath path, final VcsAppendableHistorySessionPartner partner) throws VcsException { - final VcsAbstractHistorySession emptySession = createSession(path, Collections.emptyList(), null); + @RequiredUIAccess + public void reportAppendableHistory(FilePath path, VcsAppendableHistorySessionPartner partner) throws VcsException { + VcsAbstractHistorySession emptySession = createSession(path, Collections.emptyList(), null); partner.reportCreatedEmptySession(emptySession); VcsConfiguration vcsConfiguration = VcsConfiguration.getInstance(myProject); @@ -200,7 +200,7 @@ public void reportAppendableHistory(final FilePath path, final VcsAppendableHist new String[]{"--max-count=" + vcsConfiguration.MAXIMUM_HISTORY_ROWS} : ArrayUtil.EMPTY_STRING_ARRAY; - final GitExecutableValidator validator = GitVcs.getInstance(myProject).getExecutableValidator(); + GitExecutableValidator validator = GitVcs.getInstance(myProject).getExecutableValidator(); GitHistoryUtils.history( myProject, refreshPath(path), diff --git a/plugin/src/main/java/git4idea/history/GitHistoryUtils.java b/plugin/src/main/java/git4idea/history/GitHistoryUtils.java index 75727e4..4e70396 100644 --- a/plugin/src/main/java/git4idea/history/GitHistoryUtils.java +++ b/plugin/src/main/java/git4idea/history/GitHistoryUtils.java @@ -21,7 +21,6 @@ import consulo.component.ProcessCanceledException; import consulo.git.localize.GitLocalize; import consulo.ide.ServiceManager; -import consulo.logging.Logger; import consulo.process.ProcessOutputTypes; import consulo.project.Project; import consulo.util.collection.ArrayUtil; @@ -59,6 +58,8 @@ import git4idea.log.GitRefManager; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -73,13 +74,13 @@ * A collection of methods for retrieving history information from native Git. */ public class GitHistoryUtils { + private static final Logger LOG = LoggerFactory.getLogger(GitHistoryUtils.class); + /** * A parameter to {@code git log} which is equivalent to {@code --all}, but doesn't show the stuff from index or stash. */ public static final List LOG_ALL = Arrays.asList("HEAD", "--branches", "--remotes", "--tags"); - private static final Logger LOG = Logger.getInstance(GitHistoryUtils.class); - private GitHistoryUtils() { } @@ -376,7 +377,7 @@ public void processTerminated(int exitCode) { } } catch (Throwable t) { - LOG.error(t); + LOG.error("Error while terminating process", t); exceptionConsumer.accept(new VcsException("Internal error " + t.getMessage(), t)); criticalFailure.set(true); } @@ -614,7 +615,9 @@ private static void processHandlerOutputByLine( if (parseError.isNull()) { parseError.set(t); LOG.error( - "Could not parse \" " + StringUtil.escapeStringCharacters(builder.toString()) + "\"\n" + "Command " + handler.printableCommandLine(), + "Could not parse \"{}\"\nCommand {}", + StringUtil.escapeStringCharacters(builder.toString()), + handler.printableCommandLine(), t ); } @@ -901,7 +904,7 @@ record -> { for (VcsRef ref : refsInRecord) { if (!refs.add(ref)) { VcsRef otherRef = ContainerUtil.find(refs, r -> GitLogProvider.DONT_CONSIDER_SHA.equals(r, ref)); - LOG.error("Adding duplicate element " + ref + " to the set containing " + otherRef); + LOG.error("Adding duplicate element {} to the set containing {}", ref, otherRef); } } return commit; diff --git a/plugin/src/main/java/git4idea/history/browser/SymbolicRefs.java b/plugin/src/main/java/git4idea/history/browser/SymbolicRefs.java index 9777225..81f2f3f 100644 --- a/plugin/src/main/java/git4idea/history/browser/SymbolicRefs.java +++ b/plugin/src/main/java/git4idea/history/browser/SymbolicRefs.java @@ -17,105 +17,110 @@ import jakarta.annotation.Nullable; import java.util.Collection; +import java.util.SortedSet; import java.util.TreeSet; /** * @author irengrig */ public class SymbolicRefs implements SymbolicRefsI { - private GitBranch myCurrent; - private final TreeSet myLocalBranches; - private final TreeSet myRemoteBranches; - private String myTrackedRemoteName; - private String myUsername; - private AbstractHash myHeadHash; - - public SymbolicRefs() { - myLocalBranches = new TreeSet(); - myRemoteBranches = new TreeSet(); - } - - public void addRemote(final String branch) { - myRemoteBranches.add(branch); - } - - public void addLocal(final String branch) { - myLocalBranches.add(branch); - } - - public void addLocals(final Collection value) { - myLocalBranches.addAll(value); - } - - public void addRemotes(final Collection value) { - myRemoteBranches.addAll(value); - } - - public TreeSet getLocalBranches() { - return myLocalBranches; - } - - public TreeSet getRemoteBranches() { - return myRemoteBranches; - } - - @Override - @Nullable - public String getCurrentName() { - return myCurrent == null ? null : myCurrent.getName(); - } - - @Override - public GitBranch getCurrent() { - return myCurrent; - } - - public void setCurrent(GitBranch current) { - myCurrent = current; - } - - @Override - public Kind getKind(final String s) { - if (myLocalBranches.contains(s)) return Kind.LOCAL; - if (myRemoteBranches.contains(s)) return Kind.REMOTE; - return Kind.TAG; - } - - public void clear() { - myLocalBranches.clear(); - myRemoteBranches.clear(); - } - - public void setTrackedRemote(String trackedRemoteName) { - myTrackedRemoteName = trackedRemoteName; - } - - @Override - public String getTrackedRemoteName() { - return myTrackedRemoteName; - } - - @Override - public String getUsername() { - return myUsername; - } - - public void setUsername(String username) { - myUsername = username; - } - - public void setHead(AbstractHash hash) { - myHeadHash = hash; - } - - @Override - public AbstractHash getHeadHash() { - return myHeadHash; - } - - public static enum Kind { - TAG, - LOCAL, - REMOTE - } + private GitBranch myCurrent; + private final SortedSet myLocalBranches; + private final SortedSet myRemoteBranches; + private String myTrackedRemoteName; + private String myUsername; + private AbstractHash myHeadHash; + + public SymbolicRefs() { + myLocalBranches = new TreeSet<>(); + myRemoteBranches = new TreeSet<>(); + } + + public void addRemote(String branch) { + myRemoteBranches.add(branch); + } + + public void addLocal(String branch) { + myLocalBranches.add(branch); + } + + public void addLocals(Collection value) { + myLocalBranches.addAll(value); + } + + public void addRemotes(Collection value) { + myRemoteBranches.addAll(value); + } + + public SortedSet getLocalBranches() { + return myLocalBranches; + } + + public SortedSet getRemoteBranches() { + return myRemoteBranches; + } + + @Override + @Nullable + public String getCurrentName() { + return myCurrent == null ? null : myCurrent.getName(); + } + + @Override + public GitBranch getCurrent() { + return myCurrent; + } + + public void setCurrent(GitBranch current) { + myCurrent = current; + } + + @Override + public Kind getKind(String s) { + if (myLocalBranches.contains(s)) { + return Kind.LOCAL; + } + if (myRemoteBranches.contains(s)) { + return Kind.REMOTE; + } + return Kind.TAG; + } + + public void clear() { + myLocalBranches.clear(); + myRemoteBranches.clear(); + } + + public void setTrackedRemote(String trackedRemoteName) { + myTrackedRemoteName = trackedRemoteName; + } + + @Override + public String getTrackedRemoteName() { + return myTrackedRemoteName; + } + + @Override + public String getUsername() { + return myUsername; + } + + public void setUsername(String username) { + myUsername = username; + } + + public void setHead(AbstractHash hash) { + myHeadHash = hash; + } + + @Override + public AbstractHash getHeadHash() { + return myHeadHash; + } + + public static enum Kind { + TAG, + LOCAL, + REMOTE + } } diff --git a/plugin/src/main/java/git4idea/history/browser/SymbolicRefsI.java b/plugin/src/main/java/git4idea/history/browser/SymbolicRefsI.java index c80229f..3a0fe5b 100644 --- a/plugin/src/main/java/git4idea/history/browser/SymbolicRefsI.java +++ b/plugin/src/main/java/git4idea/history/browser/SymbolicRefsI.java @@ -17,7 +17,6 @@ import git4idea.GitBranch; import git4idea.history.wholeTree.AbstractHash; - import jakarta.annotation.Nullable; /** @@ -25,9 +24,9 @@ * @since 2011-12-01 */ public interface SymbolicRefsI { - /*TreeSet getLocalBranches(); + /*SortedSet getLocalBranches(); - TreeSet getRemoteBranches();*/ + SortedSet getRemoteBranches();*/ @Nullable String getCurrentName(); diff --git a/plugin/src/main/java/git4idea/log/GitLogProvider.java b/plugin/src/main/java/git4idea/log/GitLogProvider.java index efc993f..391212d 100644 --- a/plugin/src/main/java/git4idea/log/GitLogProvider.java +++ b/plugin/src/main/java/git4idea/log/GitLogProvider.java @@ -183,36 +183,40 @@ private static void validateDataAndReportError( StopWatch sw = StopWatch.start("validating data in " + root.getName()); final Set refs = ContainerUtil.map2Set(allRefs.getValues(), VcsRef::getCommitHash); - PermanentGraph.newInstance(sortedCommits, new GraphColorManager<>() { - @Override - public int getColorOfBranch(@Nonnull Hash headCommit) { - return 0; - } + PermanentGraph.newInstance( + sortedCommits, + new GraphColorManager<>() { + @Override + public int getColorOfBranch(@Nonnull Hash headCommit) { + return 0; + } - @Override - public int getColorOfFragment(@Nonnull Hash headCommit, int magicIndex) { - return 0; - } + @Override + public int getColorOfFragment(@Nonnull Hash headCommit, int magicIndex) { + return 0; + } - @Override - public int compareHeads(@Nonnull Hash head1, @Nonnull Hash head2) { - if (!refs.contains(head1) || !refs.contains(head2)) { - LOG.error( - "GitLogProvider returned inconsistent data", - AttachmentFactory.get().create("error-details.txt", printErrorDetails( - root, - allRefs, - sortedCommits, - firstBlockSyncData, - manuallyReadBranches, - currentTagNames, - commitsFromTags - )) - ); + @Override + public int compareHeads(@Nonnull Hash head1, @Nonnull Hash head2) { + if (!refs.contains(head1) || !refs.contains(head2)) { + LOG.error( + "GitLogProvider returned inconsistent data", + AttachmentFactory.get().create("error-details.txt", printErrorDetails( + root, + allRefs, + sortedCommits, + firstBlockSyncData, + manuallyReadBranches, + currentTagNames, + commitsFromTags + )) + ); + } + return 0; } - return 0; - } - }, refs); + }, + refs + ); sw.report(); } diff --git a/plugin/src/main/java/git4idea/log/GitRefManager.java b/plugin/src/main/java/git4idea/log/GitRefManager.java index 013c7e5..3887c38 100644 --- a/plugin/src/main/java/git4idea/log/GitRefManager.java +++ b/plugin/src/main/java/git4idea/log/GitRefManager.java @@ -1,6 +1,5 @@ package git4idea.log; -import consulo.logging.Logger; import consulo.util.collection.ArrayUtil; import consulo.util.collection.ContainerUtil; import consulo.util.collection.MultiMap; @@ -20,6 +19,8 @@ import git4idea.repo.GitRepository; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.awt.*; import java.io.DataInput; @@ -32,6 +33,8 @@ * @author Kirill Likhodedov */ public class GitRefManager implements VcsLogRefManager { + private static final Logger LOG = LoggerFactory.getLogger(GitRefManager.class); + public static final VcsRefType HEAD = new SimpleRefType(true, VcsLogStandardColors.Refs.TIP, "HEAD"); public static final VcsRefType LOCAL_BRANCH = new SimpleRefType(true, VcsLogStandardColors.Refs.BRANCH, "LOCAL_BRANCH"); public static final VcsRefType REMOTE_BRANCH = new SimpleRefType(true, VcsLogStandardColors.Refs.BRANCH_REF, "REMOTE_BRANCH"); @@ -42,7 +45,6 @@ public class GitRefManager implements VcsLogRefManager { public static final String MASTER = "master"; public static final String ORIGIN_MASTER = "origin/master"; - private static final Logger LOG = Logger.getInstance(GitRefManager.class); private static final String REMOTE_TABLE_SEPARATOR = " & "; private static final String SEPARATOR = "/"; @@ -98,7 +100,7 @@ public List groupForBranchFilter(@Nonnull Collection refs) { GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) { - LOG.warn("No repository for root: " + root); + LOG.warn("No repository for root: {}", root); continue; } @@ -123,7 +125,7 @@ else if (allRemote.containsKey(refName)) { } } else { - LOG.debug("Didn't find ref neither in local nor in remote branches: " + ref); + LOG.debug("Didn't find ref neither in local nor in remote branches: {}", ref); } } } @@ -254,7 +256,7 @@ private GitRepository getRepository(@Nonnull Collection references) { VcsRef ref = ObjectUtil.assertNotNull(ContainerUtil.getFirstItem(references)); GitRepository repository = myRepositoryManager.getRepositoryForRoot(ref.getRoot()); if (repository == null) { - LOG.warn("No repository for root: " + ref.getRoot()); + LOG.warn("No repository for root: {}", ref.getRoot()); } return repository; } @@ -331,50 +333,16 @@ public static VcsRefType getRefType(@Nonnull String refName) { return OTHER; } - private static class SimpleRefType implements VcsRefType { - private final boolean myIsBranch; - @Nonnull - private final Color myColor; - @Nonnull - private final String myName; - - public SimpleRefType(boolean isBranch, @Nonnull Color color, @Nonnull String typeName) { - myIsBranch = isBranch; - myColor = color; - myName = typeName; - } - - @Override - public boolean isBranch() { - return myIsBranch; - } - + private static record SimpleRefType(boolean isBranch, @Nonnull Color color, @Nonnull String typeName) implements VcsRefType { @Nonnull @Override public Color getBackgroundColor() { - return myColor; + return color; } @Override public String toString() { - return myName; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SimpleRefType type = (SimpleRefType) o; - return myIsBranch == type.myIsBranch && Objects.equals(myName, type.myName); - } - - @Override - public int hashCode() { - return Objects.hash(myIsBranch, myName); + return typeName; } } @@ -543,7 +511,7 @@ else if (type == REMOTE_BRANCH) { private boolean isTracked(@Nonnull VcsRef ref, boolean remoteBranch) { GitRepository repo = myRepositoryManager.getRepositoryForRoot(ref.getRoot()); if (repo == null) { - LOG.error("Undefined root " + ref.getRoot()); + LOG.error("Undefined root {}", ref.getRoot()); return false; } return ContainerUtil.exists( diff --git a/plugin/src/main/java/git4idea/merge/GitConflictResolver.java b/plugin/src/main/java/git4idea/merge/GitConflictResolver.java index 167346a..6ba1e75 100644 --- a/plugin/src/main/java/git4idea/merge/GitConflictResolver.java +++ b/plugin/src/main/java/git4idea/merge/GitConflictResolver.java @@ -17,7 +17,6 @@ import consulo.application.Application; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.Notification; import consulo.project.ui.notification.NotificationService; @@ -39,6 +38,8 @@ import git4idea.repo.GitRepositoryManager; import git4idea.util.StringScanner; import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.swing.event.HyperlinkEvent; import java.io.File; @@ -52,7 +53,7 @@ * The class is highly customizable, since the procedure of resolving conflicts is very common in Git operations. */ public class GitConflictResolver { - private static final Logger LOG = Logger.getInstance(GitConflictResolver.class); + private static final Logger LOG = LoggerFactory.getLogger(GitConflictResolver.class); @Nonnull private final Collection myRoots; @@ -227,7 +228,7 @@ private boolean merge(boolean mergeDialogInvokedFromNotification) { return mergeDialogInvokedFromNotification || proceedAfterAllMerged(); } else { - LOG.info("mergeFiles unmerged files remain: " + unmergedFilesAfterResolve); + LOG.info("mergeFiles unmerged files remain: {}", unmergedFilesAfterResolve); if (mergeDialogInvokedFromNotification) { notifyUnresolvedRemainAfterNotification(); } @@ -258,7 +259,7 @@ private void showMergeDialog(@Nonnull Collection initiallyUnmergedF } private void notifyException(VcsException e) { - LOG.info("mergeFiles ", e); + LOG.info("mergeFiles", e); myNotificationService.newError(VcsNotifier.IMPORTANT_ERROR_NOTIFICATION) .title(myParams.myErrorNotificationTitle) .content(LocalizeValue.localizeTODO( @@ -315,7 +316,7 @@ private Collection getUnmergedFiles(@Nonnull VirtualFile root) thro private List unmergedFiles(VirtualFile root) throws VcsException { GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) { - LOG.error("Repository not found for root " + root); + LOG.error("Repository not found for root {}", root); return Collections.emptyList(); } diff --git a/plugin/src/main/java/git4idea/merge/MergeChangeCollector.java b/plugin/src/main/java/git4idea/merge/MergeChangeCollector.java index 74f29d2..bbb41ee 100644 --- a/plugin/src/main/java/git4idea/merge/MergeChangeCollector.java +++ b/plugin/src/main/java/git4idea/merge/MergeChangeCollector.java @@ -67,9 +67,9 @@ public void collect(UpdatedFiles updates, List exceptions) { addAll(updates, FileGroup.MERGED_WITH_CONFLICT_ID, paths); // collect other changes (ignoring unmerged) - TreeSet updated = new TreeSet<>(); - TreeSet created = new TreeSet<>(); - TreeSet removed = new TreeSet<>(); + SortedSet updated = new TreeSet<>(); + SortedSet created = new TreeSet<>(); + SortedSet removed = new TreeSet<>(); String revisionsForDiff = getRevisionsForDiff(); if (revisionsForDiff == null) { diff --git a/plugin/src/main/java/git4idea/push/GitPushNativeResultParser.java b/plugin/src/main/java/git4idea/push/GitPushNativeResultParser.java index 0e4806a..4bf1e83 100644 --- a/plugin/src/main/java/git4idea/push/GitPushNativeResultParser.java +++ b/plugin/src/main/java/git4idea/push/GitPushNativeResultParser.java @@ -15,9 +15,10 @@ */ package git4idea.push; -import consulo.logging.Logger; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; @@ -87,12 +88,14 @@ * */ public class GitPushNativeResultParser { + private static final Logger LOG = LoggerFactory.getLogger(GitPushNativeResultParser.class); - private static final Logger LOG = Logger.getInstance(GitPushNativeResultParser.class); - private static final Pattern PATTERN = Pattern.compile("^.*([ +\\-\\*!=])\t" + // flag - "(\\S+):(\\S+)\t" + // from:to - "([^(]+)" + // summary maybe with a trailing space - "(?:\\((.+)\\))?.*$"); // reason + private static final Pattern PATTERN = Pattern.compile( + "^.*([ +\\-\\*!=])\t" + // flag + "(\\S+):(\\S+)\t" + // from:to + "([^(]+)" + // summary maybe with a trailing space + "(?:\\((.+)\\))?.*$" // reason + ); private static final Pattern RANGE = Pattern.compile("[0-9a-f]+[\\.]{2,3}[0-9a-f]+"); @Nonnull @@ -117,7 +120,7 @@ private static GitPushNativeResult parseRefResult(Matcher matcher, String line) GitPushNativeResult.Type type = parseType(flag); if (type == null) { - LOG.error("Couldn't parse push result type from flag [" + flag + "] in [" + line + "]"); + LOG.error("Couldn't parse push result type from flag [{}] in [{}]", flag, line); return null; } if (matcher.groupCount() < 4) { diff --git a/plugin/src/main/java/git4idea/push/GitPushOperation.java b/plugin/src/main/java/git4idea/push/GitPushOperation.java index 6b456e0..12e50a8 100644 --- a/plugin/src/main/java/git4idea/push/GitPushOperation.java +++ b/plugin/src/main/java/git4idea/push/GitPushOperation.java @@ -21,7 +21,6 @@ import consulo.application.progress.ProgressManager; import consulo.localHistory.Label; import consulo.localHistory.LocalHistory; -import consulo.logging.Logger; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.DialogWrapper; @@ -56,6 +55,8 @@ import git4idea.update.GitUpdater; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; import java.util.stream.Collectors; @@ -76,7 +77,7 @@ * */ public class GitPushOperation { - private static final Logger LOG = Logger.getInstance(GitPushOperation.class); + private static final Logger LOG = LoggerFactory.getLogger(GitPushOperation.class); private static final int MAX_PUSH_ATTEMPTS = 10; private final Project myProject; @@ -285,7 +286,7 @@ private Map push(@Nonnull List for (GitRepository repository : repositories) { PushSpec spec = myPushSpecs.get(repository); ResultWithOutput resultWithOutput = doPush(repository, spec); - LOG.debug("Pushed to " + DvcsUtil.getShortRepositoryName(repository) + ": " + resultWithOutput); + LOG.debug("Pushed to {}: {}", DvcsUtil.getShortRepositoryName(repository), resultWithOutput); GitLocalBranch source = spec.getSource().getBranch(); GitPushTarget target = spec.getTarget(); @@ -297,7 +298,7 @@ private Map push(@Nonnull List List nativeResults = resultWithOutput.parsedResults; GitPushNativeResult branchResult = getBranchResult(nativeResults); if (branchResult == null) { - LOG.error("No result for branch among: [" + nativeResults + "]\n" + "Full result: " + resultWithOutput); + LOG.error("No result for branch among: [{}]\nFull result: {}", nativeResults, resultWithOutput); continue; } List tagResults = filter( @@ -308,7 +309,7 @@ private Map push(@Nonnull List repoResult = GitPushRepoResult.convertFromNative(branchResult, tagResults, commits, source, target.remoteBranch()); } - LOG.debug("Converted result: " + repoResult); + LOG.debug("Converted result: {}", repoResult); results.put(repository, repoResult); } @@ -333,14 +334,14 @@ private int collectNumberOfPushedCommits(@Nonnull VirtualFile root, @Nonnull Git } String range = result.getRange(); if (range == null) { - LOG.error("Range of pushed commits not reported in " + result); + LOG.error("Range of pushed commits not reported in {}", result); return -1; } try { return GitHistoryUtils.history(myProject, root, range).size(); } catch (VcsException e) { - LOG.error("Couldn't collect commits from range " + range); + LOG.error("Couldn't collect commits from range {}", range); return -1; } } @@ -355,7 +356,7 @@ private void collectUpdatedFiles( List exceptions = new ArrayList<>(); collector.collect(updatedFiles, exceptions); for (VcsException exception : exceptions) { - LOG.info(exception); + LOG.info("Error while collecting updated files", exception); } } diff --git a/plugin/src/main/java/git4idea/push/GitPushResultNotification.java b/plugin/src/main/java/git4idea/push/GitPushResultNotification.java index 747c300..cc17d44 100644 --- a/plugin/src/main/java/git4idea/push/GitPushResultNotification.java +++ b/plugin/src/main/java/git4idea/push/GitPushResultNotification.java @@ -16,7 +16,6 @@ package git4idea.push; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.Notification; import consulo.project.ui.notification.NotificationGroup; @@ -35,11 +34,15 @@ import git4idea.update.GitUpdateResult; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; import java.util.Map; class GitPushResultNotification extends Notification { + private static final Logger LOG = LoggerFactory.getLogger(GitPushResultNotification.class); + public static final LocalizeValue VIEW_FILES_UPDATED_DURING_THE_PUSH = LocalizeValue.localizeTODO("View files updated during the push"); public static final String UPDATE_WITH_RESOLVED_CONFLICTS = @@ -51,8 +54,6 @@ class GitPushResultNotification extends Notification { public static final String UPDATE_WITH_ERRORS = "push was rejected, and update failed with error."; public static final String UPDATE_CANCELLED = "push was rejected, and update was cancelled."; - private static final Logger LOG = Logger.getInstance(GitPushResultNotification.class); - public GitPushResultNotification( @Nonnull NotificationGroup groupDisplayId, @Nonnull String title, @@ -195,7 +196,7 @@ private static String formRepoDescription(@Nonnull GitPushRepoResult result) { description = "failed with error: " + result.getError(); break; default: - LOG.error("Unexpected push result: " + result); + LOG.error("Unexpected push result: {}", result); description = ""; break; } diff --git a/plugin/src/main/java/git4idea/stash/GitStashChangesSaver.java b/plugin/src/main/java/git4idea/stash/GitStashChangesSaver.java index ae5d71a..f494d23 100644 --- a/plugin/src/main/java/git4idea/stash/GitStashChangesSaver.java +++ b/plugin/src/main/java/git4idea/stash/GitStashChangesSaver.java @@ -16,8 +16,8 @@ package git4idea.stash; import consulo.application.progress.ProgressIndicator; +import consulo.git.util.LazyDebug; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.NotificationService; import consulo.ui.annotation.RequiredUIAccess; @@ -40,6 +40,8 @@ import git4idea.util.GitUIUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.swing.event.HyperlinkEvent; import java.util.ArrayList; @@ -48,7 +50,7 @@ import java.util.Set; public class GitStashChangesSaver extends GitChangesSaver { - private static final Logger LOG = Logger.getInstance(GitStashChangesSaver.class); + private static final Logger LOG = LoggerFactory.getLogger(GitStashChangesSaver.class); private static final String NO_LOCAL_CHANGES_TO_SAVE = "No local changes to save"; @Nonnull @@ -68,7 +70,7 @@ public GitStashChangesSaver( @Override protected void save(@Nonnull Collection rootsToSave) throws VcsException { - LOG.info("saving " + rootsToSave); + LOG.info("saving {}", rootsToSave); for (VirtualFile root : rootsToSave) { String message = GitHandlerUtil.formatOperationName("Stashing changes from", root); @@ -111,7 +113,7 @@ public void load() { } boolean conflictsResolved = new UnstashConflictResolver(myProject, myGit, myStashedRoots, myParams).merge(); - LOG.info("load: conflicts resolved status is " + conflictsResolved + " in roots " + myStashedRoots); + LOG.info("load: conflicts resolved status is {} in roots {}", conflictsResolved, myStashedRoots); } @Override @@ -141,12 +143,12 @@ public void showSavedChanges() { * False is returned in all other cases: in the case of success and in case of some other error. */ private boolean loadRoot(VirtualFile root) { - LOG.info("loadRoot " + root); + LOG.info("loadRoot {}", root); myProgressIndicator.setText(GitHandlerUtil.formatOperationName("Unstashing changes to", root)); GitRepository repository = myRepositoryManager.getRepositoryForRoot(root); if (repository == null) { - LOG.error("Repository is null for root " + root); + LOG.error("Repository is null for root {}", root); return false; } @@ -160,7 +162,7 @@ else if (conflictDetector.hasHappened()) { return true; } else { - LOG.info("unstash failed " + result.getErrorOutputAsJoinedString()); + LOG.info("unstash failed {}", new LazyDebug(result::getErrorOutputAsJoinedString)); GitUIUtil.notifyImportantError( myProject, LocalizeValue.localizeTODO("Couldn't unstash"), diff --git a/plugin/src/main/java/git4idea/status/GitChangeProvider.java b/plugin/src/main/java/git4idea/status/GitChangeProvider.java index a08c0c7..f42addf 100644 --- a/plugin/src/main/java/git4idea/status/GitChangeProvider.java +++ b/plugin/src/main/java/git4idea/status/GitChangeProvider.java @@ -21,7 +21,6 @@ import consulo.application.progress.ProgressIndicator; import consulo.document.Document; import consulo.document.FileDocumentManager; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.io.FileUtil; import consulo.versionControlSystem.FilePath; @@ -44,6 +43,8 @@ import jakarta.annotation.Nonnull; import jakarta.inject.Inject; import jakarta.inject.Singleton; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; @@ -54,8 +55,7 @@ @ServiceAPI(ComponentScope.PROJECT) @ServiceImpl public class GitChangeProvider implements ChangeProvider { - - private static final Logger LOG = Logger.getInstance("#GitStatus"); + private static final Logger LOG = LoggerFactory.getLogger("#GitStatus"); @Nonnull private final Project myProject; @@ -69,8 +69,10 @@ public class GitChangeProvider implements ChangeProvider { private final ProjectLevelVcsManager myVcsManager; @Inject - public GitChangeProvider(@Nonnull Project project, @Nonnull Git git, @Nonnull ChangeListManager changeListManager, - @Nonnull FileDocumentManager fileDocumentManager, @Nonnull ProjectLevelVcsManager vcsManager) { + public GitChangeProvider( + @Nonnull Project project, @Nonnull Git git, @Nonnull ChangeListManager changeListManager, + @Nonnull FileDocumentManager fileDocumentManager, @Nonnull ProjectLevelVcsManager vcsManager + ) { myProject = project; myGit = git; myChangeListManager = changeListManager; @@ -79,11 +81,13 @@ public GitChangeProvider(@Nonnull Project project, @Nonnull Git git, @Nonnull Ch } @Override - public void getChanges(final VcsDirtyScope dirtyScope, - final ChangelistBuilder builder, - final ProgressIndicator progress, - final ChangeListManagerGate addGate) throws VcsException { - final GitVcs vcs = GitVcs.getInstance(myProject); + public void getChanges( + VcsDirtyScope dirtyScope, + ChangelistBuilder builder, + ProgressIndicator progress, + ChangeListManagerGate addGate + ) throws VcsException { + GitVcs vcs = GitVcs.getInstance(myProject); if (vcs == null) { // already disposed or not yet initialized => ignoring return; @@ -91,22 +95,28 @@ public void getChanges(final VcsDirtyScope dirtyScope, appendNestedVcsRootsToDirt(dirtyScope, vcs, myVcsManager); - final Collection affected = dirtyScope.getAffectedContentRoots(); + Collection affected = dirtyScope.getAffectedContentRoots(); Collection roots = GitUtil.gitRootsForPaths(affected); try { - final NonChangedHolder holder = new NonChangedHolder(myProject, addGate, - myFileDocumentManager); + NonChangedHolder holder = new NonChangedHolder(myProject, addGate, myFileDocumentManager); for (VirtualFile root : roots) { - debug("checking root: " + root.getPath()); - GitNewChangesCollector collector = GitNewChangesCollector.collect(myProject, myGit, myChangeListManager, myVcsManager, - vcs, dirtyScope, root); - final Collection changes = collector.getChanges(); + LOG.debug("checking root: {}", root.getPath()); + GitNewChangesCollector collector = GitNewChangesCollector.collect( + myProject, + myGit, + myChangeListManager, + myVcsManager, + vcs, + dirtyScope, + root + ); + Collection changes = collector.getChanges(); holder.markHeadRevision(root, collector.getHead()); for (Change file : changes) { FilePath filePath = ChangesUtil.getFilePath(file); - debug("process change: " + filePath.getPath()); + LOG.debug("process change: {}", filePath.getPath()); builder.processChange(file, GitVcs.getKey()); holder.markPathProcessed(filePath); @@ -120,22 +130,22 @@ public void getChanges(final VcsDirtyScope dirtyScope, } } catch (VcsException e) { - LOG.info(e); + LOG.info("Error while getting changes", e); // most probably the error happened because git is not configured vcs.getExecutableValidator().showNotificationOrThrow(e); } } - public static void appendNestedVcsRootsToDirt(final VcsDirtyScope dirtyScope, GitVcs vcs, final ProjectLevelVcsManager vcsManager) { - final Set recursivelyDirtyDirectories = dirtyScope.getRecursivelyDirtyDirectories(); + public static void appendNestedVcsRootsToDirt(VcsDirtyScope dirtyScope, GitVcs vcs, ProjectLevelVcsManager vcsManager) { + Set recursivelyDirtyDirectories = dirtyScope.getRecursivelyDirtyDirectories(); if (recursivelyDirtyDirectories.isEmpty()) { return; } - final LocalFileSystem lfs = LocalFileSystem.getInstance(); - final Set rootsUnderGit = new HashSet(Arrays.asList(vcsManager.getRootsUnderVcs(vcs))); - final Set inputColl = new HashSet(rootsUnderGit); - final Set existingInScope = new HashSet(); + LocalFileSystem lfs = LocalFileSystem.getInstance(); + Set rootsUnderGit = new HashSet<>(Arrays.asList(vcsManager.getRootsUnderVcs(vcs))); + Set inputColl = new HashSet<>(rootsUnderGit); + Set existingInScope = new HashSet<>(); for (FilePath dir : recursivelyDirtyDirectories) { VirtualFile vf = dir.getVirtualFile(); if (vf == null) { @@ -149,9 +159,12 @@ public static void appendNestedVcsRootsToDirt(final VcsDirtyScope dirtyScope, Gi } } inputColl.addAll(existingInScope); - FileUtil.removeAncestors(inputColl, o -> o.getPath(), (parent, child) -> { + FileUtil.removeAncestors( + inputColl, + VirtualFile::getPath, + (parent, child) -> { if (!existingInScope.contains(child) && existingInScope.contains(parent)) { - debug("adding git root for check: " + child.getPath()); + LOG.debug("adding git root for check: {}", child.getPath()); ((VcsModifiableDirtyScope) dirtyScope).addDirtyDirRecursively(VcsContextFactory.getInstance().createFilePathOn(child)); } return true; @@ -159,14 +172,6 @@ public static void appendNestedVcsRootsToDirt(final VcsDirtyScope dirtyScope, Gi ); } - /** - * Common debug logging method for all Git status related operations. - * Primarily used for measuring performance and tracking calls to heavy methods. - */ - public static void debug(String message) { - LOG.debug(message); - } - private static class NonChangedHolder { private final Project myProject; private final ChangeListManagerGate myAddGate; @@ -175,9 +180,11 @@ private static class NonChangedHolder { private final Set myProcessedPaths = new HashSet<>(); private final Map myHeadRevisions = new HashMap<>(); - private NonChangedHolder(Project project, - ChangeListManagerGate addGate, - FileDocumentManager fileDocumentManager) { + private NonChangedHolder( + Project project, + ChangeListManagerGate addGate, + FileDocumentManager fileDocumentManager + ) { myProject = project; myAddGate = addGate; myFileDocumentManager = fileDocumentManager; @@ -191,8 +198,8 @@ public void markHeadRevision(@Nonnull VirtualFile root, @Nonnull VcsRevisionNumb myHeadRevisions.put(root, revision); } - public void feedBuilder(@Nonnull VcsDirtyScope dirtyScope, final ChangelistBuilder builder) throws VcsException { - final VcsKey gitKey = GitVcs.getKey(); + public void feedBuilder(@Nonnull VcsDirtyScope dirtyScope, ChangelistBuilder builder) throws VcsException { + VcsKey gitKey = GitVcs.getKey(); for (Document document : myFileDocumentManager.getUnsavedDocuments()) { VirtualFile vf = myFileDocumentManager.getFile(document); @@ -234,9 +241,10 @@ public void feedBuilder(@Nonnull VcsDirtyScope dirtyScope, final ChangelistBuild } Change change = new Change(GitContentRevision.createRevision(vf, beforeRevisionNumber, myProject), - GitContentRevision.createRevision(vf, null, myProject), FileStatus.MODIFIED); + GitContentRevision.createRevision(vf, null, myProject), FileStatus.MODIFIED + ); - LOG.debug("process in-memory change ", change); + LOG.debug("process in-memory change {}", change); builder.processChange(change, gitKey); } } @@ -248,6 +256,6 @@ public boolean isModifiedDocumentTrackingRequired() { } @Override - public void doCleanup(final List files) { + public void doCleanup(List files) { } } diff --git a/plugin/src/main/java/git4idea/status/GitNewChangesCollector.java b/plugin/src/main/java/git4idea/status/GitNewChangesCollector.java index 8d53173..d299c5b 100644 --- a/plugin/src/main/java/git4idea/status/GitNewChangesCollector.java +++ b/plugin/src/main/java/git4idea/status/GitNewChangesCollector.java @@ -15,7 +15,6 @@ */ package git4idea.status; -import consulo.logging.Logger; import consulo.project.Project; import consulo.util.lang.StringUtil; import consulo.versionControlSystem.AbstractVcs; @@ -40,7 +39,6 @@ import git4idea.repo.GitRepository; import git4idea.repo.GitUntrackedFilesHolder; import jakarta.annotation.Nonnull; -import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.HashSet; @@ -59,11 +57,9 @@ * @author Kirill Likhodedov */ public class GitNewChangesCollector extends GitChangesCollector { - - private static final Logger LOG = Logger.getInstance(GitNewChangesCollector.class); private final GitRepository myRepository; - private final Collection myChanges = new HashSet(); - private final Set myUnversionedFiles = new HashSet(); + private final Collection myChanges = new HashSet<>(); + private final Set myUnversionedFiles = new HashSet<>(); @Nonnull private final Git myGit; private final VcsRevisionNumber myHead; @@ -131,7 +127,7 @@ private void collectUnversionedFiles() throws VcsException { private GitSimpleHandler statusHandler(Collection dirtyPaths) { GitSimpleHandler handler = new GitSimpleHandler(myProject, myVcsRoot, GitCommand.STATUS); - final String[] params = {"--porcelain", "-z", "--untracked-files=no"}; // untracked files are stored separately + String[] params = {"--porcelain", "-z", "--untracked-files=no"}; // untracked files are stored separately handler.addParameters(params); handler.setSilent(true); handler.setStdoutSuppressed(true); @@ -156,7 +152,7 @@ private GitSimpleHandler statusHandler(Collection dirtyPaths) { private void parseOutput(@Nonnull String output, @Nonnull GitHandler handler) throws VcsException { VcsRevisionNumber head = getHead(); - final String[] split = output.split("\u0000"); + String[] split = output.split("\u0000"); for (int pos = 0; pos < split.length; pos++) { String line = split[pos]; @@ -168,10 +164,10 @@ private void parseOutput(@Nonnull String output, @Nonnull GitHandler handler) th if (line.length() < 4) { // X, Y, space and at least one symbol for the file throwGFE("Line is too short.", handler, output, line, '0', '0'); } - final String xyStatus = line.substring(0, 2); - final String filepath = line.substring(3); // skipping the space - final char xStatus = xyStatus.charAt(0); - final char yStatus = xyStatus.charAt(1); + String xyStatus = line.substring(0, 2); + String filepath = line.substring(3); // skipping the space + char xStatus = xyStatus.charAt(0); + char yStatus = xyStatus.charAt(1); switch (xStatus) { case ' ': @@ -293,12 +289,12 @@ else if (yStatus == 'D') { } } - @NotNull - static VcsRevisionNumber getHead(@NotNull GitRepository repository) { + @Nonnull + static VcsRevisionNumber getHead(@Nonnull GitRepository repository) { // we force update the GitRepository, because update is asynchronous, and thus the GitChangeProvider may be asked for changes // before the GitRepositoryUpdater has captures the current revision change and has updated the GitRepository. repository.update(); - final String rev = repository.getCurrentRevision(); + String rev = repository.getCurrentRevision(); return rev != null ? new GitRevisionNumber(rev) : VcsRevisionNumber.NULL; } diff --git a/plugin/src/main/java/git4idea/ui/GitRepositoryComboboxListCellRenderer.java b/plugin/src/main/java/git4idea/ui/GitRepositoryComboboxListCellRenderer.java index 231ef26..e94ec95 100644 --- a/plugin/src/main/java/git4idea/ui/GitRepositoryComboboxListCellRenderer.java +++ b/plugin/src/main/java/git4idea/ui/GitRepositoryComboboxListCellRenderer.java @@ -25,20 +25,18 @@ /** * Common {@link ListCellRenderer} do be used in {@link JComboBox} displaying {@link GitRepository GitRepositories}. * We don't want to use {@link GitRepository#toString()} since it is not the best way to display the repository in the UI. - * + * * @author Kirill Likhodedov */ public class GitRepositoryComboboxListCellRenderer extends ListCellRendererWrapper { + private static final DefaultListCellRenderer DEFAULT_RENDERER = new DefaultListCellRenderer(); - private static final DefaultListCellRenderer DEFAULT_RENDERER = new DefaultListCellRenderer(); - - public GitRepositoryComboboxListCellRenderer(final JComboBox comboBox) { - super(); - } - - @Override - public void customize(JList list, GitRepository value, int index, boolean selected, boolean hasFocus) { - setText(DvcsUtil.getShortRepositoryName(value)); - } + public GitRepositoryComboboxListCellRenderer(JComboBox comboBox) { + super(); + } + @Override + public void customize(JList list, GitRepository value, int index, boolean selected, boolean hasFocus) { + setText(DvcsUtil.getShortRepositoryName(value)); + } } diff --git a/plugin/src/main/java/git4idea/ui/GitUnstashDialog.java b/plugin/src/main/java/git4idea/ui/GitUnstashDialog.java index 2e100cf..6a4665d 100644 --- a/plugin/src/main/java/git4idea/ui/GitUnstashDialog.java +++ b/plugin/src/main/java/git4idea/ui/GitUnstashDialog.java @@ -24,7 +24,6 @@ import consulo.git.localize.GitLocalize; import consulo.ide.ServiceManager; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.platform.base.localize.CommonLocalize; import consulo.process.cmd.GeneralCommandLine; import consulo.project.Project; @@ -52,6 +51,8 @@ import git4idea.util.GitUIUtil; import git4idea.validators.GitBranchNameValidator; import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -67,6 +68,8 @@ * The unstash dialog */ public class GitUnstashDialog extends DialogWrapper { + private static final Logger LOG = LoggerFactory.getLogger(GitUnstashDialog.class); + /** * Git root selector */ @@ -115,7 +118,6 @@ public class GitUnstashDialog extends DialogWrapper { @Nonnull private final Project myProject; private GitVcs myVcs; - private static final Logger LOG = Logger.getInstance(GitUnstashDialog.class); /** * A constructor @@ -305,7 +307,7 @@ private void refreshStashList() { myBranches.addAll(GitBranchUtil.convertBranchesToNames(repository.getBranches().getLocalBranches())); } else { - LOG.error("Repository is null for root " + root); + LOG.error("Repository is null for root {}", root); } myStashList.setSelectedIndex(0); } @@ -396,7 +398,7 @@ public void onLineAvailable(String line, Key outputType) { if (conflict.get()) { boolean conflictsResolved = new UnstashConflictResolver(myProject, root, getSelectedStash()).merge(); - LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved); + LOG.info("loadRoot {}, conflictsResolved: {}", root, conflictsResolved); } else if (rc != 0) { GitUIUtil.showOperationErrors(myProject, h.errors(), LocalizeValue.of(h.printableCommandLine())); diff --git a/plugin/src/main/java/git4idea/update/GitMergeUpdater.java b/plugin/src/main/java/git4idea/update/GitMergeUpdater.java index 65c20bc..94d3083 100644 --- a/plugin/src/main/java/git4idea/update/GitMergeUpdater.java +++ b/plugin/src/main/java/git4idea/update/GitMergeUpdater.java @@ -18,8 +18,8 @@ import consulo.application.Application; import consulo.application.progress.ProgressIndicator; import consulo.component.ProcessCanceledException; +import consulo.git.util.LazyDebug; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.UIUtil; @@ -47,6 +47,8 @@ import git4idea.util.GitUIUtil; import git4idea.util.GitUntrackedFilesHelper; import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.util.*; @@ -58,7 +60,7 @@ * Handles {@code git pull} via merge. */ public class GitMergeUpdater extends GitUpdater { - private static final Logger LOG = Logger.getInstance(GitMergeUpdater.class); + private static final Logger LOG = LoggerFactory.getLogger(GitMergeUpdater.class); @Nonnull private final ChangeListManager myChangeListManager; @@ -79,7 +81,7 @@ public GitMergeUpdater( @Override @RequiredUIAccess protected GitUpdateResult doUpdate() { - LOG.info("doUpdate "); + LOG.info("doUpdate"); GitMerger merger = new GitMerger(myProject); MergeLineListener mergeLineListener = new MergeLineListener(); @@ -117,7 +119,7 @@ private GitUpdateResult handleMergeFailure( @Nonnull LocalizeValue errorMessage ) { MergeError error = mergeLineListener.getMergeError(); - LOG.info("merge error: " + error); + LOG.info("merge error: {}", error); if (error == MergeError.CONFLICT) { LOG.info("Conflict detected"); boolean allMerged = new MyConflictResolver(myProject, myGit, merger, myRoot).merge(); @@ -151,7 +153,7 @@ else if (untrackedFilesWouldBeOverwrittenByMergeDetector.wasMessageDetected()) { return GitUpdateResult.ERROR; } else { - LOG.info("Unknown error: " + errorMessage); + LOG.info("Unknown error: {}", errorMessage); GitUIUtil.notifyImportantError(myProject, LocalizeValue.localizeTODO("Error merging"), errorMessage); return GitUpdateResult.ERROR; } @@ -175,7 +177,7 @@ public boolean isSaveNeeded() { try { GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(myRoot); if (repository == null) { - LOG.error("Repository is null for root " + myRoot); + LOG.error("Repository is null for root {}", myRoot); return true; // fail safe } Collection remotelyChanged = @@ -193,7 +195,7 @@ public boolean isSaveNeeded() { return false; } catch (VcsException e) { - LOG.info("failed to get remotely changed files for " + currentBranch + ".." + remoteBranch, e); + LOG.info("failed to get remotely changed files for {}..{}", currentBranch, remoteBranch, e); return true; // fail safe } } @@ -203,7 +205,7 @@ private void cancel() { h.addParameters("--merge"); GitCommandResult result = Git.getInstance().runCommand(h); if (!result.success()) { - LOG.info("cancel git reset --merge: " + result.getErrorOutputAsJoinedString()); + LOG.info("cancel git reset --merge: {}", new LazyDebug(result::getErrorOutputAsJoinedString)); GitUIUtil.notifyImportantError( myProject, LocalizeValue.localizeTODO("Couldn't reset merge"), diff --git a/plugin/src/main/java/git4idea/update/GitRebaseOverMergeProblem.java b/plugin/src/main/java/git4idea/update/GitRebaseOverMergeProblem.java index 9d8ec43..650dc47 100644 --- a/plugin/src/main/java/git4idea/update/GitRebaseOverMergeProblem.java +++ b/plugin/src/main/java/git4idea/update/GitRebaseOverMergeProblem.java @@ -15,101 +15,113 @@ */ package git4idea.update; -import consulo.application.ApplicationManager; -import consulo.application.CommonBundle; -import consulo.logging.Logger; +import consulo.application.Application; +import consulo.localize.LocalizeValue; +import consulo.platform.base.localize.CommonLocalize; import consulo.project.Project; -import consulo.ui.ex.awt.Messages; +import consulo.ui.annotation.RequiredUIAccess; +import consulo.ui.ex.awt.UIUtil; import consulo.util.collection.ContainerUtil; import consulo.util.lang.ObjectUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import consulo.versionControlSystem.VcsException; import consulo.versionControlSystem.log.TimedVcsCommit; import consulo.virtualFileSystem.VirtualFile; import git4idea.DialogManager; import git4idea.history.GitHistoryUtils; - import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.Arrays; import java.util.function.Consumer; public class GitRebaseOverMergeProblem { - private static final Logger LOG = Logger.getInstance(GitRebaseOverMergeProblem.class); - public static final String DESCRIPTION = "You are about to rebase merge commits. \n" + - "This can lead to duplicate commits in history, or even data loss.\n" + - "It is recommended to merge instead of rebase in this case."; + private static final Logger LOG = LoggerFactory.getLogger(GitRebaseOverMergeProblem.class); + public static final String DESCRIPTION = "You are about to rebase merge commits.\n" + + "This can lead to duplicate commits in history, or even data loss.\n" + + "It is recommended to merge instead of rebase in this case."; - public enum Decision { - MERGE_INSTEAD("Merge"), - REBASE_ANYWAY("Rebase Anyway"), - CANCEL_OPERATION(CommonBundle.getCancelButtonText()); + public enum Decision { + MERGE_INSTEAD(LocalizeValue.localizeTODO("Merge")), + REBASE_ANYWAY(LocalizeValue.localizeTODO("Rebase Anyway")), + CANCEL_OPERATION(CommonLocalize.buttonCancel()); - private final String myButtonText; + @Nonnull + private final LocalizeValue myButtonText; - Decision(@Nonnull String buttonText) { - myButtonText = buttonText; - } + Decision(@Nonnull LocalizeValue buttonText) { + myButtonText = buttonText; + } - @Nonnull - private static String[] getButtonTitles() { - return ContainerUtil.map2Array(values(), String.class, decision -> decision.myButtonText); - } + @Nonnull + private static String[] getButtonTitles() { + return ContainerUtil.map2Array(values(), String.class, decision -> decision.myButtonText.get()); + } - @Nonnull - public static Decision getOption(final int index) { - return ObjectUtil.assertNotNull(ContainerUtil.find(values(), decision -> decision.ordinal() == index)); - } + @Nonnull + public static Decision getOption(int index) { + return ObjectUtil.assertNotNull(ContainerUtil.find(values(), decision -> decision.ordinal() == index)); + } - private static int getDefaultButtonIndex() { - return MERGE_INSTEAD.ordinal(); - } + private static int getDefaultButtonIndex() { + return MERGE_INSTEAD.ordinal(); + } - private static int getFocusedButtonIndex() { - return CANCEL_OPERATION.ordinal(); + private static int getFocusedButtonIndex() { + return CANCEL_OPERATION.ordinal(); + } } - } - public static boolean hasProblem(@Nonnull Project project, - @Nonnull VirtualFile root, - @Nonnull String baseRef, - @Nonnull String currentRef) { - final Ref mergeFound = Ref.create(Boolean.FALSE); - Consumer detectingConsumer = commit -> mergeFound.set(true); + public static boolean hasProblem( + @Nonnull Project project, + @Nonnull VirtualFile root, + @Nonnull String baseRef, + @Nonnull String currentRef + ) { + SimpleReference mergeFound = SimpleReference.create(Boolean.FALSE); + Consumer detectingConsumer = commit -> mergeFound.set(true); - String range = baseRef + ".." + currentRef; - try { - GitHistoryUtils.readCommits(project, root, Arrays.asList(range, "--merges"), e -> { - }, - e -> { - }, detectingConsumer); - } - catch (VcsException e) { - LOG.warn("Couldn't get git log --merges " + range, e); + String range = baseRef + ".." + currentRef; + try { + GitHistoryUtils.readCommits( + project, + root, + Arrays.asList(range, "--merges"), + e -> { + }, + e -> { + }, + detectingConsumer + ); + } + catch (VcsException e) { + LOG.warn("Couldn't get git log --merges {}", range, e); + } + return mergeFound.get(); } - return mergeFound.get(); - } - @Nonnull - public static Decision showDialog() { - final Ref decision = Ref.create(); - ApplicationManager.getApplication().invokeAndWait(new Runnable() { - @Override - public void run() { - decision.set(doShowDialog()); - } - }, ApplicationManager.getApplication().getDefaultModalityState()); - return decision.get(); - } + @Nonnull + @RequiredUIAccess + public static Decision showDialog() { + SimpleReference decision = SimpleReference.create(); + Application application = Application.get(); + application.invokeAndWait(() -> decision.set(doShowDialog()), application.getDefaultModalityState()); + return decision.get(); + } - @Nonnull - private static Decision doShowDialog() { - int decision = DialogManager.showMessage(DESCRIPTION, - "Rebasing Merge Commits", - Decision.getButtonTitles(), - Decision.getDefaultButtonIndex(), - Decision.getFocusedButtonIndex(), - Messages.getWarningIcon(), - null); - return Decision.getOption(decision); - } + @Nonnull + @RequiredUIAccess + private static Decision doShowDialog() { + int decision = DialogManager.showMessage( + DESCRIPTION, + "Rebasing Merge Commits", + Decision.getButtonTitles(), + Decision.getDefaultButtonIndex(), + Decision.getFocusedButtonIndex(), + UIUtil.getWarningIcon(), + null + ); + return Decision.getOption(decision); + } } diff --git a/plugin/src/main/java/git4idea/update/GitUpdateProcess.java b/plugin/src/main/java/git4idea/update/GitUpdateProcess.java index 4386e06..bc75354 100644 --- a/plugin/src/main/java/git4idea/update/GitUpdateProcess.java +++ b/plugin/src/main/java/git4idea/update/GitUpdateProcess.java @@ -19,7 +19,6 @@ import consulo.application.progress.EmptyProgressIndicator; import consulo.application.progress.ProgressIndicator; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.util.collection.ContainerUtil; @@ -50,6 +49,8 @@ import git4idea.util.GitPreservingProcess; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; @@ -64,7 +65,7 @@ * @author Kirill Likhodedov */ public class GitUpdateProcess { - private static final Logger LOG = Logger.getInstance(GitUpdateProcess.class); + private static final Logger LOG = LoggerFactory.getLogger(GitUpdateProcess.class); @Nonnull private final Project myProject; @@ -122,7 +123,7 @@ public GitUpdateProcess( @Nonnull @RequiredUIAccess public GitUpdateResult update(UpdateMethod updateMethod) { - LOG.info("update started|" + updateMethod); + LOG.info("update started|{}", updateMethod); LocalizeValue oldText = myProgressIndicator.getTextValue(); myProgressIndicator.setTextValue(LocalizeValue.localizeTODO("Updating...")); @@ -162,7 +163,7 @@ private GitUpdateResult updateImpl(@Nonnull UpdateMethod updateMethod) { updaters = defineUpdaters(updateMethod, trackedBranches); } catch (VcsException e) { - LOG.info(e); + LOG.info("Error while defining updaters", e); notifyError(myProject, LocalizeValue.localizeTODO("Git update failed"), LocalizeValue.ofNullable(e.getMessage()), true, e); return GitUpdateResult.ERROR; } @@ -187,7 +188,7 @@ private GitUpdateResult updateImpl(@Nonnull UpdateMethod updateMethod) { VirtualFile root = repo.getRoot(); GitBranchPair branchAndTracked = trackedBranches.get(root); if (branchAndTracked == null) { - LOG.error("No tracked branch information for root " + root); + LOG.error("No tracked branch information for root {}", root); continue; } updaters.put( @@ -210,7 +211,7 @@ else if (decision == GitRebaseOverMergeProblem.Decision.CANCEL_OPERATION) { GitUpdater updater = entry.getValue(); if (updater.isSaveNeeded()) { myRootsToSave.add(repo.getRoot()); - LOG.info("update| root " + repo + " needs save"); + LOG.info("update| root {} needs save", repo); } } @@ -237,7 +238,7 @@ else if (decision == GitRebaseOverMergeProblem.Decision.CANCEL_OPERATION) { } currentlyUpdatedRoot = repo; GitUpdateResult res = updater.update(); - LOG.info("updating root " + currentlyUpdatedRoot + " finished: " + res); + LOG.info("updating root {} finished: {}", currentlyUpdatedRoot, res); if (res == GitUpdateResult.INCOMPLETE) { incomplete.set(true); } @@ -246,7 +247,7 @@ else if (decision == GitRebaseOverMergeProblem.Decision.CANCEL_OPERATION) { } catch (VcsException e) { String rootName = (currentlyUpdatedRoot == null) ? "" : getShortRepositoryName(currentlyUpdatedRoot); - LOG.info("Error updating changes for root " + currentlyUpdatedRoot, e); + LOG.info("Error updating changes for root {}", currentlyUpdatedRoot, e); notifyImportantError( myProject, LocalizeValue.localizeTODO("Error updating " + rootName), @@ -291,7 +292,7 @@ private Map tryFastForwardMergeForRebaseUpdaters(@Non continue; } Collection changes = changesUnderRoots.get(repository.getRoot()); - LOG.debug("Changes under root '" + getShortRepositoryName(repository) + "': " + changes); + LOG.debug("Changes under root '{}': {}", getShortRepositoryName(repository), changes); // check only if there are local changes, otherwise stash won't happen anyway and there would be no optimization if (updater instanceof GitRebaseUpdater rebaseUpdater && changes != null && !changes.isEmpty() @@ -321,7 +322,7 @@ private Map defineUpdaters( if (updater.isUpdateNeeded()) { updaters.put(repository, updater); } - LOG.info("update| root=" + root + " ,updater=" + updater); + LOG.info("update| root={}, updater={}", root, updater); } return updaters; } @@ -353,7 +354,7 @@ private Map checkTrackedBranchesConfiguration() { VirtualFile root = repository.getRoot(); GitLocalBranch branch = repository.getCurrentBranch(); if (branch == null) { - LOG.info("checkTrackedBranchesConfigured: current branch is null in " + repository); + LOG.info("checkTrackedBranchesConfigured: current branch is null in {}", repository); notifyImportantError( myProject, LocalizeValue.localizeTODO("Can't update: no current branch"), @@ -366,7 +367,7 @@ private Map checkTrackedBranchesConfiguration() { } GitBranchTrackInfo trackInfo = GitBranchUtil.getTrackInfoForBranch(repository, branch); if (trackInfo == null) { - LOG.info(String.format("checkTrackedBranchesConfigured: no track info for current branch %s in %s", branch, repository)); + LOG.info("checkTrackedBranchesConfigured: no track info for current branch {} in {}", branch, repository); if (myCheckForTrackedBranchExistence) { notifyImportantError( repository.getProject(), @@ -414,7 +415,7 @@ private boolean isMergeInProgress() { if (mergingRoots.isEmpty()) { return false; } - LOG.info("isMergeInProgress: roots with unfinished merge: " + mergingRoots); + LOG.info("isMergeInProgress: roots with unfinished merge: {}", mergingRoots); GitConflictResolver.Params params = new GitConflictResolver.Params() .setErrorNotificationTitle(LocalizeValue.localizeTODO("Can't update")) .setMergeDescription(LocalizeValue.localizeTODO("You have unfinished merge. These conflicts must be resolved before update.")); @@ -455,7 +456,7 @@ private boolean checkRebaseInProgress() { if (rebasingRoots.isEmpty()) { return false; } - LOG.info("checkRebaseInProgress: roots with unfinished rebase: " + rebasingRoots); + LOG.info("checkRebaseInProgress: roots with unfinished rebase: {}", rebasingRoots); GitConflictResolver.Params params = new GitConflictResolver.Params() .setErrorNotificationTitle(LocalizeValue.localizeTODO("Can't update")) diff --git a/plugin/src/main/java/git4idea/update/GitUpdater.java b/plugin/src/main/java/git4idea/update/GitUpdater.java index acdbfbe..c95ef45 100644 --- a/plugin/src/main/java/git4idea/update/GitUpdater.java +++ b/plugin/src/main/java/git4idea/update/GitUpdater.java @@ -15,26 +15,13 @@ */ package git4idea.update; -import static git4idea.GitUtil.HEAD; -import static git4idea.config.UpdateMethod.MERGE; -import static git4idea.config.UpdateMethod.REBASE; - -import java.util.ArrayList; -import java.util.List; - -import jakarta.annotation.Nonnull; -import consulo.logging.Logger; import consulo.application.progress.ProgressIndicator; import consulo.project.Project; -import consulo.versionControlSystem.VcsException; -import consulo.virtualFileSystem.VirtualFile; import consulo.versionControlSystem.AbstractVcsHelper; +import consulo.versionControlSystem.VcsException; import consulo.versionControlSystem.update.UpdatedFiles; -import git4idea.GitBranch; -import git4idea.GitLocalBranch; -import git4idea.GitRevisionNumber; -import git4idea.GitUtil; -import git4idea.GitVcs; +import consulo.virtualFileSystem.VirtualFile; +import git4idea.*; import git4idea.branch.GitBranchPair; import git4idea.commands.Git; import git4idea.commands.GitCommand; @@ -45,6 +32,16 @@ import git4idea.merge.MergeChangeCollector; import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; +import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +import static git4idea.GitUtil.HEAD; +import static git4idea.config.UpdateMethod.MERGE; +import static git4idea.config.UpdateMethod.REBASE; /** * Updates a single repository via merge or rebase. @@ -53,7 +50,7 @@ * @see GitMergeUpdater */ public abstract class GitUpdater { - private static final Logger LOG = Logger.getInstance(GitUpdater.class); + private static final Logger LOG = LoggerFactory.getLogger(GitUpdater.class); @Nonnull protected final Project myProject; @@ -136,11 +133,11 @@ public static UpdateMethod resolveUpdateMethod(@Nonnull GitRepository repository // explicit override of a more generic pull.rebase config value return MERGE; } - LOG.warn("Unknown value for branch." + branchName + ".rebase: " + rebaseValue); + LOG.warn("Unknown value for branch.{}.rebase: {}", branchName, rebaseValue); } } catch (VcsException e) { - LOG.warn("Couldn't get git config branch." + branchName + ".rebase"); + LOG.warn("Couldn't get git config branch.{}.rebase", branchName); } } diff --git a/plugin/src/main/java/git4idea/util/GitCommitCompareInfo.java b/plugin/src/main/java/git4idea/util/GitCommitCompareInfo.java index b337eab..666586d 100644 --- a/plugin/src/main/java/git4idea/util/GitCommitCompareInfo.java +++ b/plugin/src/main/java/git4idea/util/GitCommitCompareInfo.java @@ -15,12 +15,13 @@ */ package git4idea.util; -import consulo.logging.Logger; import consulo.util.lang.Couple; import consulo.versionControlSystem.change.Change; import git4idea.GitCommit; import git4idea.repo.GitRepository; import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; @@ -28,7 +29,8 @@ * @author Kirill Likhodedov */ public class GitCommitCompareInfo { - private static final Logger LOG = Logger.getInstance(GitCommitCompareInfo.class); + private static final Logger LOG = LoggerFactory.getLogger(GitCommitCompareInfo.class); + private final Map>> myInfo = new HashMap<>(); private final Map> myTotalDiff = new HashMap<>(); private final InfoType myInfoType; @@ -63,7 +65,7 @@ public List getBranchToHeadCommits(@Nonnull GitRepository repo) { private Couple> getCompareInfo(@Nonnull GitRepository repo) { Couple> pair = myInfo.get(repo); if (pair == null) { - LOG.error("Compare info not found for repository " + repo); + LOG.error("Compare info not found for repository {}", repo); return Couple.of(Collections.emptyList(), Collections.emptyList()); } return pair; diff --git a/plugin/src/main/java/git4idea/util/GitFileUtils.java b/plugin/src/main/java/git4idea/util/GitFileUtils.java index e907692..315e4d2 100644 --- a/plugin/src/main/java/git4idea/util/GitFileUtils.java +++ b/plugin/src/main/java/git4idea/util/GitFileUtils.java @@ -15,8 +15,7 @@ */ package git4idea.util; -import consulo.application.util.SystemInfo; -import consulo.logging.Logger; +import consulo.platform.Platform; import consulo.project.Project; import consulo.util.lang.StringUtil; import consulo.versionControlSystem.FilePath; @@ -28,222 +27,235 @@ import git4idea.commands.GitCommand; import git4idea.commands.GitSimpleHandler; import git4idea.repo.GitRepository; - import jakarta.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.*; /** * File utilities for the git */ public class GitFileUtils { - private static final Logger LOG = Logger.getInstance(GitFileUtils.class); - - /** - * The private constructor for static utility class - */ - private GitFileUtils() { - // do nothing - } - - /** - * Delete files - * - * @param project the project - * @param root a vcs root - * @param files files to delete - * @return a result of operation - * @throws VcsException in case of git problem - */ - - public static void delete(Project project, VirtualFile root, Collection files, String... additionalOptions) - throws VcsException { - for (List paths : VcsFileUtil.chunkPaths(root, files)) { - GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM); - handler.addParameters(additionalOptions); - handler.endOptions(); - handler.addParameters(paths); - handler.run(); - } - } - - /** - * Delete files - * - * @param project the project - * @param root a vcs root - * @param files files to delete - * @return a result of operation - * @throws VcsException in case of git problem - */ - public static void deleteFiles(Project project, VirtualFile root, Collection files, String... additionalOptions) - throws VcsException { - for (List paths : VcsFileUtil.chunkFiles(root, files)) { - GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM); - handler.addParameters(additionalOptions); - handler.endOptions(); - handler.addParameters(paths); - handler.run(); - } - } - - /** - * Delete files - * - * @param project the project - * @param root a vcs root - * @param files files to delete - * @return a result of operation - * @throws VcsException in case of git problem - */ - public static void deleteFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException { - deleteFiles(project, root, Arrays.asList(files)); - } - - /** - * Delete files from cache (mark untracked) - * - * @param project the project - * @param root a vcs root - * @param files files to delete - * @return a result of operation - * @throws VcsException in case of git problem - */ - public static void deleteFilesFromCache(@Nonnull Project project, @Nonnull VirtualFile root, @Nonnull Collection files) - throws VcsException { - deleteFiles(project, root, files, "--cached"); - updateUntrackedFilesHolderOnFileRemove(project, root, files); - } - - /** - * Add files to the Git index. - */ - public static void addFiles(@Nonnull Project project, @Nonnull VirtualFile root, @Nonnull Collection files) - throws VcsException { - addPaths(project, root, VcsFileUtil.chunkFiles(root, files)); - updateUntrackedFilesHolderOnFileAdd(project, root, files); - } - - private static void updateUntrackedFilesHolderOnFileAdd(@Nonnull Project project, @Nonnull VirtualFile root, - @Nonnull Collection addedFiles) { - final GitRepository repository = GitUtil.getRepositoryManager(project).getRepositoryForRoot(root); - if (repository == null) { - LOG.error("Repository not found for root " + root.getPresentableUrl()); - return; - } - repository.getUntrackedFilesHolder().remove(addedFiles); - } - - private static void updateUntrackedFilesHolderOnFileRemove(@Nonnull Project project, @Nonnull VirtualFile root, - @Nonnull Collection removedFiles) { - final GitRepository repository = GitUtil.getRepositoryManager(project).getRepositoryForRoot(root); - if (repository == null) { - LOG.error("Repository not found for root " + root.getPresentableUrl()); - return; - } - repository.getUntrackedFilesHolder().add(removedFiles); - } - - /** - * Add files to the Git index. - */ - public static void addFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException { - addFiles(project, root, Arrays.asList(files)); - } - - /** - * Add files to the Git index. - */ - public static void addPaths(@Nonnull Project project, @Nonnull VirtualFile root, - @Nonnull Collection files) throws VcsException { - addPaths(project, root, VcsFileUtil.chunkPaths(root, files)); - updateUntrackedFilesHolderOnFileAdd(project, root, getVirtualFilesFromFilePaths(files)); - } - - @Nonnull - private static Collection getVirtualFilesFromFilePaths(@Nonnull Collection paths) { - Collection files = new ArrayList(paths.size()); - for (FilePath path : paths) { - VirtualFile file = path.getVirtualFile(); - if (file != null) { - files.add(file); - } - } - return files; - } - - private static void addPaths(@Nonnull Project project, @Nonnull VirtualFile root, - @Nonnull List> chunkedPaths) throws VcsException { - for (List paths : chunkedPaths) { - paths = excludeIgnoredFiles(project, root, paths); - - if (paths.isEmpty()) { - continue; - } - GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.ADD); - handler.addParameters("--ignore-errors"); - handler.endOptions(); - handler.addParameters(paths); - handler.run(); - } - } - - @Nonnull - private static List excludeIgnoredFiles(@Nonnull Project project, @Nonnull VirtualFile root, - @Nonnull List paths) throws VcsException { - GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.LS_FILES); - handler.setSilent(true); - handler.addParameters("--ignored", "--others", "--exclude-standard"); - handler.endOptions(); - handler.addParameters(paths); - String output = handler.run(); - - List nonIgnoredFiles = new ArrayList(paths.size()); - Set ignoredPaths = new HashSet(Arrays.asList(StringUtil.splitByLines(output))); - for (String pathToCheck : paths) { - if (!ignoredPaths.contains(pathToCheck)) { - nonIgnoredFiles.add(pathToCheck); - } - } - return nonIgnoredFiles; - } - - /** - * Get file content for the specific revision - * - * @param project the project - * @param root the vcs root - * @param revisionOrBranch the revision to find path in or branch - * @param relativePath - * @return the content of file if file is found, null if the file is missing in the revision - * @throws VcsException if there is a problem with running git - */ - public static byte[] getFileContent(Project project, VirtualFile root, String revisionOrBranch, String relativePath) throws VcsException { - GitBinaryHandler h = new GitBinaryHandler(project, root, GitCommand.SHOW); - h.setSilent(true); - h.addParameters(revisionOrBranch + ":" + relativePath); - return h.run(); - } - - public static String stripFileProtocolPrefix(String path) { - final String FILE_PROTOCOL = "file://"; - if (path.startsWith(FILE_PROTOCOL)) { - return path.substring(FILE_PROTOCOL.length()); - } - return path; - } - - /** - * Checks if two file paths are different only by case in a case insensitive OS. - * @return true if the difference between paths should probably be ignored, i.e. the OS is case-insensitive, and case is the only - * difference between paths. - */ - public static boolean shouldIgnoreCaseChange(@Nonnull String onePath, @Nonnull String secondPath) { - return !SystemInfo.isFileSystemCaseSensitive && onlyCaseChanged(onePath, secondPath); - } - - private static boolean onlyCaseChanged(@Nonnull String one, @Nonnull String second) { - return one.compareToIgnoreCase(second) == 0; - } - + private static final Logger LOG = LoggerFactory.getLogger(GitFileUtils.class); + + /** + * The private constructor for static utility class + */ + private GitFileUtils() { + // do nothing + } + + /** + * Delete files + * + * @param project the project + * @param root a vcs root + * @param files files to delete + * @throws VcsException in case of git problem + */ + public static void delete(Project project, VirtualFile root, Collection files, String... additionalOptions) + throws VcsException { + for (List paths : VcsFileUtil.chunkPaths(root, files)) { + GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM); + handler.addParameters(additionalOptions); + handler.endOptions(); + handler.addParameters(paths); + handler.run(); + } + } + + /** + * Delete files + * + * @param project the project + * @param root a vcs root + * @param files files to delete + * @throws VcsException in case of git problem + */ + public static void deleteFiles(Project project, VirtualFile root, Collection files, String... additionalOptions) + throws VcsException { + for (List paths : VcsFileUtil.chunkFiles(root, files)) { + GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.RM); + handler.addParameters(additionalOptions); + handler.endOptions(); + handler.addParameters(paths); + handler.run(); + } + } + + /** + * Delete files + * + * @param project the project + * @param root a vcs root + * @param files files to delete + * @throws VcsException in case of git problem + */ + public static void deleteFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException { + deleteFiles(project, root, Arrays.asList(files)); + } + /** + * Delete files from cache (mark untracked) + * + * @param project the project + * @param root a vcs root + * @param files files to delete + * @throws VcsException in case of git problem + */ + public static void deleteFilesFromCache(@Nonnull Project project, @Nonnull VirtualFile root, @Nonnull Collection files) + throws VcsException { + deleteFiles(project, root, files, "--cached"); + updateUntrackedFilesHolderOnFileRemove(project, root, files); + } + + /** + * Add files to the Git index. + */ + public static void addFiles(@Nonnull Project project, @Nonnull VirtualFile root, @Nonnull Collection files) + throws VcsException { + addPaths(project, root, VcsFileUtil.chunkFiles(root, files)); + updateUntrackedFilesHolderOnFileAdd(project, root, files); + } + + private static void updateUntrackedFilesHolderOnFileAdd( + @Nonnull Project project, + @Nonnull VirtualFile root, + @Nonnull Collection addedFiles + ) { + GitRepository repository = GitUtil.getRepositoryManager(project).getRepositoryForRoot(root); + if (repository == null) { + LOG.error("Repository not found for root {}", root.getPresentableUrl()); + return; + } + repository.getUntrackedFilesHolder().remove(addedFiles); + } + + private static void updateUntrackedFilesHolderOnFileRemove( + @Nonnull Project project, + @Nonnull VirtualFile root, + @Nonnull Collection removedFiles + ) { + GitRepository repository = GitUtil.getRepositoryManager(project).getRepositoryForRoot(root); + if (repository == null) { + LOG.error("Repository not found for root {}", root.getPresentableUrl()); + return; + } + repository.getUntrackedFilesHolder().add(removedFiles); + } + + /** + * Add files to the Git index. + */ + public static void addFiles(Project project, VirtualFile root, VirtualFile... files) throws VcsException { + addFiles(project, root, Arrays.asList(files)); + } + + /** + * Add files to the Git index. + */ + public static void addPaths( + @Nonnull Project project, @Nonnull VirtualFile root, + @Nonnull Collection files + ) throws VcsException { + addPaths(project, root, VcsFileUtil.chunkPaths(root, files)); + updateUntrackedFilesHolderOnFileAdd(project, root, getVirtualFilesFromFilePaths(files)); + } + + @Nonnull + private static Collection getVirtualFilesFromFilePaths(@Nonnull Collection paths) { + Collection files = new ArrayList<>(paths.size()); + for (FilePath path : paths) { + VirtualFile file = path.getVirtualFile(); + if (file != null) { + files.add(file); + } + } + return files; + } + + private static void addPaths( + @Nonnull Project project, @Nonnull VirtualFile root, + @Nonnull List> chunkedPaths + ) throws VcsException { + for (List paths : chunkedPaths) { + paths = excludeIgnoredFiles(project, root, paths); + + if (paths.isEmpty()) { + continue; + } + GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.ADD); + handler.addParameters("--ignore-errors"); + handler.endOptions(); + handler.addParameters(paths); + handler.run(); + } + } + + @Nonnull + private static List excludeIgnoredFiles( + @Nonnull Project project, @Nonnull VirtualFile root, + @Nonnull List paths + ) throws VcsException { + GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.LS_FILES); + handler.setSilent(true); + handler.addParameters("--ignored", "--others", "--exclude-standard"); + handler.endOptions(); + handler.addParameters(paths); + String output = handler.run(); + + List nonIgnoredFiles = new ArrayList<>(paths.size()); + Set ignoredPaths = new HashSet<>(Arrays.asList(StringUtil.splitByLines(output))); + for (String pathToCheck : paths) { + if (!ignoredPaths.contains(pathToCheck)) { + nonIgnoredFiles.add(pathToCheck); + } + } + return nonIgnoredFiles; + } + + /** + * Get file content for the specific revision + * + * @param project the project + * @param root the vcs root + * @param revisionOrBranch the revision to find path in or branch + * @param relativePath + * @return the content of file if file is found, null if the file is missing in the revision + * @throws VcsException if there is a problem with running git + */ + public static byte[] getFileContent( + Project project, + VirtualFile root, + String revisionOrBranch, + String relativePath + ) throws VcsException { + GitBinaryHandler h = new GitBinaryHandler(project, root, GitCommand.SHOW); + h.setSilent(true); + h.addParameters(revisionOrBranch + ":" + relativePath); + return h.run(); + } + + public static String stripFileProtocolPrefix(String path) { + String FILE_PROTOCOL = "file://"; + if (path.startsWith(FILE_PROTOCOL)) { + return path.substring(FILE_PROTOCOL.length()); + } + return path; + } + + /** + * Checks if two file paths are different only by case in a case insensitive OS. + * + * @return true if the difference between paths should probably be ignored, i.e. the OS is case-insensitive, and case is the only + * difference between paths. + */ + public static boolean shouldIgnoreCaseChange(@Nonnull String onePath, @Nonnull String secondPath) { + return !Platform.current().fs().isCaseSensitive() && onlyCaseChanged(onePath, secondPath); + } + + private static boolean onlyCaseChanged(@Nonnull String one, @Nonnull String second) { + return one.compareToIgnoreCase(second) == 0; + } } diff --git a/plugin/src/main/java/git4idea/util/GitPreservingProcess.java b/plugin/src/main/java/git4idea/util/GitPreservingProcess.java index 83a261e..1411bba 100644 --- a/plugin/src/main/java/git4idea/util/GitPreservingProcess.java +++ b/plugin/src/main/java/git4idea/util/GitPreservingProcess.java @@ -18,7 +18,6 @@ import consulo.application.progress.ProgressIndicator; import consulo.application.util.DateFormatUtil; import consulo.localize.LocalizeValue; -import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ui.notification.NotificationService; import consulo.util.lang.Clock; @@ -32,9 +31,10 @@ import git4idea.config.GitVcsSettings; import git4idea.merge.GitConflictResolver; import git4idea.stash.GitChangesSaver; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; @@ -45,7 +45,7 @@ * I.e. stashes changes, executes the operation and then unstashes it. */ public class GitPreservingProcess { - private static final Logger LOG = Logger.getInstance(GitPreservingProcess.class); + private static final Logger LOG = LoggerFactory.getLogger(GitPreservingProcess.class); @Nonnull private final Project myProject; @@ -102,7 +102,7 @@ public void execute(@Nullable Supplier autoLoadDecision) { Runnable operation = () -> { LOG.debug("starting"); boolean savedSuccessfully = save(); - LOG.debug("save result: " + savedSuccessfully); + LOG.debug("save result: {}", savedSuccessfully); if (savedSuccessfully) { try { LOG.debug("running operation");