diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/UnshelvePatchDefaultExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/UnshelvePatchDefaultExecutor.java index f8be4986c464..19424e079524 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/UnshelvePatchDefaultExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/UnshelvePatchDefaultExecutor.java @@ -37,6 +37,8 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import static com.intellij.util.containers.ContainerUtil.mapNotNull; + public class UnshelvePatchDefaultExecutor extends ApplyPatchDefaultExecutor { private static final Logger LOG = Logger.getInstance(UnshelvePatchDefaultExecutor.class); @@ -73,16 +75,11 @@ public class UnshelvePatchDefaultExecutor extends ApplyPatchDefaultExecutor { for (PatchApplier applier : appliers) { patches.addAll(applier.getRemainingPatches()); } - if (patches.isEmpty()) { - shelveChangesManager.recycleChangeList(myCurrentShelveChangeList); - } - else { - shelveChangesManager.saveRemainingPatches(myCurrentShelveChangeList, patches, - ContainerUtil.mapNotNull(patches, patch -> patch instanceof ShelvedBinaryFilePatch - ? ((ShelvedBinaryFilePatch)patch) - .getShelvedBinaryFile() - : null), commitContext, false); - } + shelveChangesManager + .updateListAfterUnshelve(myCurrentShelveChangeList, patches, mapNotNull(patches, patch -> patch instanceof ShelvedBinaryFilePatch + ? ((ShelvedBinaryFilePatch)patch) + .getShelvedBinaryFile() + : null), commitContext); } catch (Exception e) { LOG.error("Couldn't update and store remaining patches", e); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java index 09119849dfbb..875f90b9905a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java @@ -679,12 +679,7 @@ public class ShelveChangesManager implements JDOMExternalizable, ProjectComponen patchApplier.execute(showSuccessNotification, systemOperation); if (isRemoveFilesFromShelf() || systemOperation) { remainingPatches.addAll(patchApplier.getRemainingPatches()); - if (remainingPatches.isEmpty() && remainingBinaries.isEmpty()) { - recycleChangeList(changeList); - } - else { - saveRemainingPatches(changeList, remainingPatches, remainingBinaries, commitContext, false); - } + updateListAfterUnshelve(changeList, remainingPatches, remainingBinaries, commitContext); } }); } @@ -703,23 +698,34 @@ public class ShelveChangesManager implements JDOMExternalizable, ProjectComponen } //store original dates to restore if needed - Map createdDeletedListsWithOriginalDate = newHashMap(); + Map deletedListsWithOriginalDate = newHashMap(); for (ShelvedChangeList changeList : shelvedListsToDelete) { Date originalDate = changeList.DATE; - ShelvedChangeList recentlyDeleted = deleteChangeList(changeList); - //was not completely deleted - if (recentlyDeleted != null) { - createdDeletedListsWithOriginalDate.put(recentlyDeleted, originalDate); + if (changeList.isDeleted()) { + deleteChangeListCompletely(changeList); + } + else { + markChangeListAsDeleted(changeList); + deletedListsWithOriginalDate.put(changeList, originalDate); } } + for (ShelvedChangeList list : shelvedListsFromChangesToDelete) { Date originalDate = list.DATE; - ShelvedChangeList listWithDeletedChanges = removeChangesFromChangeList(list, changesToDelete, binariesToDelete); - if (listWithDeletedChanges != null) { - createdDeletedListsWithOriginalDate.put(listWithDeletedChanges, originalDate); + boolean wasDeleted = list.isDeleted(); + ShelvedChangeList newListWithDeletedChanges = removeChangesFromChangeList(list, changesToDelete, binariesToDelete); + if (newListWithDeletedChanges != null) { + deletedListsWithOriginalDate.put(newListWithDeletedChanges, originalDate); + } + else if (!wasDeleted) { + //entire list became deleted because no changes remained + ShelvedChangeList shelvedChangeList = mySchemeManager.findSchemeByName(list.getName()); + if (shelvedChangeList != null && shelvedChangeList.isDeleted()) { + deletedListsWithOriginalDate.put(shelvedChangeList, originalDate); + } } } - return createdDeletedListsWithOriginalDate; + return deletedListsWithOriginalDate; } @Nullable @@ -739,12 +745,7 @@ public class ShelveChangesManager implements JDOMExternalizable, ProjectComponen VcsImplUtil.showErrorMessage(myProject, e.getMessage(), "Cannot delete files from " + list.DESCRIPTION); return null; } - if (remainingPatches.isEmpty() && remainingBinaries.isEmpty()) { - return deleteChangeList(list); - } - else { - return saveRemainingPatches(list, remainingPatches, remainingBinaries, commitContext, true); - } + return saveRemainingPatchesIfNeeded(list, remainingPatches, remainingBinaries, commitContext, true); } @@ -956,14 +957,43 @@ public class ShelveChangesManager implements JDOMExternalizable, ProjectComponen } } + public void updateListAfterUnshelve(@NotNull ShelvedChangeList listToUpdate, + @NotNull List patches, + @NotNull List binaries, + @NotNull CommitContext commitContext) { + saveRemainingPatchesIfNeeded(listToUpdate, patches, binaries, commitContext, false); + } + + /** + * Return newly created shelved list with applied (deleted or unshelved) changes or null if no additional shelved list was created + * 1. if no changes remained in the original list - delete or mark applied (recycled) entire list - > no new list created, return null; + * 2. if there are some applied (deleted) changes and something remained it the original list then create separated list for applied + * changes and delete these changes from the original list - > in this case new list with applied (deleted) changes will be a return value + */ @Nullable - public ShelvedChangeList saveRemainingPatches(final ShelvedChangeList changeList, - final List remainingPatches, - final List remainingBinaries, - CommitContext commitContext, - boolean delete) { + private ShelvedChangeList saveRemainingPatchesIfNeeded(final ShelvedChangeList changeList, + final List remainingPatches, + final List remainingBinaries, + CommitContext commitContext, + boolean delete) { + // all changes in the shelved list have been chosen to be applied/deleted + if (remainingPatches.isEmpty() && remainingBinaries.isEmpty()) { + if (!delete) { + recycleChangeList(changeList); + } + else if (changeList.isDeleted()) { + deleteChangeListCompletely(changeList); + } + else { + markChangeListAsDeleted(changeList); + } + return null; + } + //apply already applied - do not change anything + if (!delete && changeList.isRecycled()) return null; + ShelvedChangeList newlyCreatedList = null; - if ((delete && changeList.isDeleted()) || (!delete && changeList.isRecycled())) { + if ((delete && changeList.isDeleted())) { saveRemainingChangesInList(changeList, remainingPatches, remainingBinaries, commitContext); } else { @@ -991,8 +1021,7 @@ public class ShelveChangesManager implements JDOMExternalizable, ProjectComponen removeFromList(listCopy, changeList.getChanges(myProject), changeList.getBinaryFiles()); if (delete) { - //if completely deleted -> return null; - if (deleteChangeList(listCopy) == null) return null; + markChangeListAsDeleted(listCopy); } else { recycleChangeList(listCopy); @@ -1113,7 +1142,7 @@ public class ShelveChangesManager implements JDOMExternalizable, ProjectComponen } } - public void recycleChangeList(@NotNull final ShelvedChangeList changeList) { + private void recycleChangeList(@NotNull final ShelvedChangeList changeList) { changeList.setRecycled(true); changeList.updateDate(); if (changeList.isMarkedToDelete()) { @@ -1123,26 +1152,16 @@ public class ShelveChangesManager implements JDOMExternalizable, ProjectComponen notifyStateChanged(); } + private void deleteChangeListCompletely(@NotNull final ShelvedChangeList changeList) { + deleteResources(changeList); + mySchemeManager.removeScheme(changeList); + notifyStateChanged(); + } - /** - * Remove changelist completely or mark as deleted - * - * @param changeList list to delete or to mark as deleted - * @return changelist if marked as deleted or null if was completely removed - */ - public ShelvedChangeList deleteChangeList(@NotNull final ShelvedChangeList changeList) { - ShelvedChangeList deletedList = null; - if (changeList.isDeleted()) { - deleteResources(changeList); - mySchemeManager.removeScheme(changeList); - } - else { - changeList.setDeleted(true); - changeList.updateDate(); - deletedList = changeList; - } + void markChangeListAsDeleted(@NotNull final ShelvedChangeList changeList) { + changeList.setDeleted(true); + changeList.updateDate(); notifyStateChanged(); - return deletedList; } private void deleteResources(@NotNull final ShelvedChangeList changeList) { diff --git a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManagerTest.kt b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManagerTest.kt index efeb8b380413..ef11f8f47e80 100644 --- a/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManagerTest.kt +++ b/platform/vcs-tests/testSrc/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManagerTest.kt @@ -57,19 +57,19 @@ class ShelveChangesManagerTest : PlatformTestCase() { fun `test delete deleted list`() { val shelvedChangeList = myShelvedChangesManager.shelvedChangeLists[0] - myShelvedChangesManager.deleteChangeList(shelvedChangeList) + myShelvedChangesManager.markChangeListAsDeleted(shelvedChangeList) doTestDelete(shelvedChangeList, 0, 0, 2, 0) } fun `test delete deleted files`() { val shelvedChangeList = myShelvedChangesManager.shelvedChangeLists[0] - myShelvedChangesManager.deleteChangeList(shelvedChangeList) + myShelvedChangesManager.markChangeListAsDeleted(shelvedChangeList) doTestDelete(shelvedChangeList, 1, 1, 2, 1) } fun `test delete all deleted files`() { val shelvedChangeList = myShelvedChangesManager.shelvedChangeLists[0] - myShelvedChangesManager.deleteChangeList(shelvedChangeList) + myShelvedChangesManager.markChangeListAsDeleted(shelvedChangeList) doTestDelete(shelvedChangeList, 2, 2, 2, 0) }