mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
git: restore case-only renames after commit via staging area
This commit is contained in:
@@ -74,6 +74,7 @@ import git4idea.index.GitIndexUtil;
|
||||
import git4idea.repo.GitRepository;
|
||||
import git4idea.repo.GitRepositoryManager;
|
||||
import git4idea.util.GitFileUtils;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -301,7 +302,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
!removed.contains(getBeforePath(change)));
|
||||
if (!excludedStagedChanges.isEmpty()) {
|
||||
LOG.info("Staged changes excluded for commit: " + GitUtil.getLogString(rootPath, excludedStagedChanges));
|
||||
reset(project, root, excludedStagedChanges);
|
||||
resetExcluded(project, root, excludedStagedChanges);
|
||||
}
|
||||
try {
|
||||
List<FilePath> alreadyHandledPaths = getPaths(changedWithIndex);
|
||||
@@ -324,12 +325,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
finally {
|
||||
// Stage back the changes unstaged before commit
|
||||
if (!excludedStagedChanges.isEmpty()) {
|
||||
Set<FilePath> toAdd = map2SetNotNull(excludedStagedChanges, ChangesUtil::getAfterPath);
|
||||
Set<FilePath> toRemove = map2SetNotNull(excludedStagedChanges, ChangesUtil::getBeforePath);
|
||||
toRemove.removeAll(toAdd);
|
||||
|
||||
LOG.debug(String.format("Restoring staged changes after commit: added: %s, removed: %s", toAdd, toRemove));
|
||||
updateIndex(project, root, toAdd, toRemove, exceptions);
|
||||
restoreExcluded(project, root, excludedStagedChanges, exceptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,8 +654,10 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
}
|
||||
|
||||
|
||||
private static void reset(@NotNull Project project, @NotNull VirtualFile root, @NotNull Collection<Change> changes) throws VcsException {
|
||||
Set<FilePath> allPaths = new HashSet<>();
|
||||
private static void resetExcluded(@NotNull Project project,
|
||||
@NotNull VirtualFile root,
|
||||
@NotNull Collection<Change> changes) throws VcsException {
|
||||
Set<FilePath> allPaths = new THashSet<>(CASE_SENSITIVE_FILE_PATH_HASHING_STRATEGY);
|
||||
allPaths.addAll(mapNotNull(changes, ChangesUtil::getAfterPath));
|
||||
allPaths.addAll(mapNotNull(changes, ChangesUtil::getBeforePath));
|
||||
|
||||
@@ -671,6 +669,46 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
|
||||
}
|
||||
}
|
||||
|
||||
private static void restoreExcluded(@NotNull Project project,
|
||||
@NotNull VirtualFile root,
|
||||
@NotNull Collection<Change> changes,
|
||||
@NotNull List<VcsException> exceptions) throws VcsException {
|
||||
Set<FilePath> toAdd = new HashSet<>();
|
||||
Set<FilePath> toRemove = new HashSet<>();
|
||||
|
||||
for (Change change : changes) {
|
||||
if (addAsCaseOnlyRename(project, root, change)) continue;
|
||||
|
||||
addIfNotNull(toAdd, getAfterPath(change));
|
||||
addIfNotNull(toRemove, getBeforePath(change));
|
||||
}
|
||||
toRemove.removeAll(toAdd);
|
||||
|
||||
LOG.debug(String.format("Restoring staged changes after commit: added: %s, removed: %s", toAdd, toRemove));
|
||||
updateIndex(project, root, toAdd, toRemove, exceptions);
|
||||
}
|
||||
|
||||
private static boolean addAsCaseOnlyRename(@NotNull Project project, @NotNull VirtualFile root, @NotNull Change change) {
|
||||
try {
|
||||
CommitChange commitChange = new CommitChange(change);
|
||||
if (!isCaseOnlyRename(commitChange)) return false;
|
||||
|
||||
FilePath beforePath = assertNotNull(commitChange.beforePath);
|
||||
FilePath afterPath = assertNotNull(commitChange.afterPath);
|
||||
|
||||
LOG.debug(String.format("Restoring staged case-only rename after commit: %s", change));
|
||||
GitLineHandler h = new GitLineHandler(project, root, GitCommand.MV);
|
||||
h.addParameters("-f", beforePath.getPath(), afterPath.getPath());
|
||||
Git.getInstance().runCommandWithoutCollectingOutput(h).getOutputOrThrow();
|
||||
return true;
|
||||
}
|
||||
catch (VcsException e) {
|
||||
LOG.warn(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<VcsException> commit(List<Change> changes, String preparedComment) {
|
||||
return commit(changes, preparedComment, FunctionUtil.nullConstant(), null);
|
||||
}
|
||||
|
||||
@@ -73,10 +73,11 @@ fun GitRepository.assertCommitted(depth: Int = 1, changes: ChangesBuilder.() ->
|
||||
val cb = ChangesBuilder()
|
||||
cb.changes()
|
||||
|
||||
val actualChanges = GitHistoryUtils.history(project, root, "-${depth}")[depth - 1].changes
|
||||
val allCanges = GitHistoryUtils.history(project, root, "-${depth}")[depth - 1].changes
|
||||
val actualChanges = allCanges.toMutableSet()
|
||||
for (change in cb.changes) {
|
||||
val found = actualChanges.find(change.matcher)
|
||||
PlatformTestCase.assertNotNull("The change [$change] wasn't committed", found)
|
||||
PlatformTestCase.assertNotNull("The change [$change] wasn't committed\n$allCanges", found)
|
||||
actualChanges.remove(found)
|
||||
}
|
||||
PlatformTestCase.assertTrue(actualChanges.isEmpty())
|
||||
|
||||
@@ -308,6 +308,31 @@ class GitCommitTest : GitSingleRepoTest() {
|
||||
}
|
||||
}
|
||||
|
||||
fun `test commit case rename & don't commit one staged case rename`() {
|
||||
`assume version where git reset returns 0 exit code on success `()
|
||||
|
||||
tac("s.java")
|
||||
generateCaseRename("a.java", "A.java")
|
||||
git("mv s.java S.java")
|
||||
|
||||
val changes = assertChanges {
|
||||
rename("a.java", "A.java")
|
||||
rename("s.java", "S.java")
|
||||
}
|
||||
|
||||
commit(listOf(changes[0]))
|
||||
|
||||
repo.assertCommitted {
|
||||
rename("a.java", "A.java")
|
||||
}
|
||||
assertChanges {
|
||||
rename("s.java", "S.java")
|
||||
}
|
||||
repo.assertStagedChanges {
|
||||
rename("s.java", "S.java")
|
||||
}
|
||||
}
|
||||
|
||||
fun `test commit case rename & don't commit one staged simple rename, then rename should remain staged`() {
|
||||
`assume version where git reset returns 0 exit code on success `()
|
||||
|
||||
@@ -540,12 +565,13 @@ class GitCommitTest : GitSingleRepoTest() {
|
||||
cb.changes()
|
||||
|
||||
updateChangeListManager()
|
||||
val vcsChanges = changeListManager.allChanges
|
||||
val allChanges = mutableListOf<Change>()
|
||||
val actualChanges = HashSet(changeListManager.allChanges)
|
||||
val actualChanges = HashSet(vcsChanges)
|
||||
|
||||
for (change in cb.changes) {
|
||||
val found = actualChanges.find(change.matcher)
|
||||
assertNotNull("The change [$change] not found", found)
|
||||
assertNotNull("The change [$change] not found\n$vcsChanges", found)
|
||||
actualChanges.remove(found)
|
||||
allChanges.add(found!!)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user