git update/push: when shelving local changes, create technical changelist for every local changelist, for easier manual recovery in case of failure

This commit is contained in:
irengrig
2012-06-19 13:33:02 +04:00
parent 11c48b0c2a
commit 06fd1b4c07
2 changed files with 57 additions and 33 deletions
@@ -19,20 +19,14 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsRoot;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangesUtil;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.*;
/**
* Utility class to sort changes by roots.
@@ -52,6 +46,19 @@ public class LocalChangesUnderRoots {
myVcsManager = ProjectLevelVcsManager.getInstance(myProject);
}
public Map<String, Map<VirtualFile, Collection<Change>>> getChangesByLists(@NotNull Collection<VirtualFile> rootsToSave) {
final Map<String, Map<VirtualFile, Collection<Change>>> result = new HashMap<String, Map<VirtualFile, Collection<Change>>>();
myRoots = myVcsManager.getAllVcsRoots();
final List<LocalChangeList> changeLists = myChangeManager.getChangeListsCopy();
for (LocalChangeList list : changeLists) {
final HashMap<VirtualFile, Collection<Change>> subMap = new HashMap<VirtualFile, Collection<Change>>();
addChangesToMap(rootsToSave, subMap, list.getChanges());
result.put(list.getName(), subMap);
}
return result;
}
/**
* Sort all changes registered in the {@link ChangeListManager} by VCS roots,
* filtering out any roots except the specified ones.
@@ -64,6 +71,13 @@ public class LocalChangesUnderRoots {
final Collection<Change> allChanges = myChangeManager.getAllChanges();
myRoots = myVcsManager.getAllVcsRoots();
addChangesToMap(rootsToSave, result, allChanges);
return result;
}
private void addChangesToMap(Collection<VirtualFile> rootsToSave,
Map<VirtualFile, Collection<Change>> result,
Collection<Change> allChanges) {
for (Change change : allChanges) {
if (change.getBeforeRevision() != null) {
addChangeToMap(result, change, change.getBeforeRevision(), rootsToSave);
@@ -72,7 +86,6 @@ public class LocalChangesUnderRoots {
addChangeToMap(result, change, change.getAfterRevision(), rootsToSave);
}
}
return result;
}
private void addChangeToMap(@NotNull Map<VirtualFile, Collection<Change>> result, @NotNull Change change, @NotNull ContentRevision revision, @NotNull Collection<VirtualFile> rootsToSave) {
@@ -40,7 +40,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
private static final Logger LOG = Logger.getInstance(GitShelveChangesSaver.class);
private final ShelveChangesManager myShelveManager;
private final ShelvedChangesViewManager myShelveViewManager;
private ShelvedChangeList myShelvedChangeList;
private Map<String, ShelvedChangeList> myShelvedLists;
public GitShelveChangesSaver(Project project, Git git, ProgressIndicator indicator, String stashMessage) {
super(project, git, indicator, stashMessage);
@@ -51,35 +51,46 @@ public class GitShelveChangesSaver extends GitChangesSaver {
@Override
protected void save(@NotNull Collection<VirtualFile> rootsToSave) throws VcsException {
LOG.info("save " + rootsToSave);
final Map<VirtualFile,Collection<Change>> map = new LocalChangesUnderRoots(myProject).getChangesUnderRoots(rootsToSave);
final Set<Change> changes = new HashSet<Change>();
for (Collection<Change> changeCollection : map.values()) {
changes.addAll(changeCollection);
}
if (! changes.isEmpty()) {
String oldProgressTitle = myProgressIndicator.getText();
myProgressIndicator.setText(GitBundle.getString("update.shelving.changes"));
List<VcsException> exceptions = new ArrayList<VcsException>(1);
myShelvedChangeList = GitShelveUtils.shelveChanges(myProject, myShelveManager, changes, myStashMessage, exceptions, false);
myProgressIndicator.setText(oldProgressTitle);
if (! exceptions.isEmpty()) {
LOG.info("save " + exceptions, exceptions.get(0));
throw exceptions.get(0);
} else {
for (VirtualFile root : rootsToSave) {
GitRollbackEnvironment.resetHardLocal(myProject, root);
}
final Map<String, Map<VirtualFile, Collection<Change>>> lists = new LocalChangesUnderRoots(myProject).getChangesByLists(rootsToSave);
String oldProgressTitle = myProgressIndicator.getText();
myProgressIndicator.setText(GitBundle.getString("update.shelving.changes"));
List<VcsException> exceptions = new ArrayList<VcsException>(1);
myShelvedLists = new HashMap<String, ShelvedChangeList>();
for (Map.Entry<String, Map<VirtualFile, Collection<Change>>> entry : lists.entrySet()) {
final Map<VirtualFile, Collection<Change>> map = entry.getValue();
final Set<Change> changes = new HashSet<Change>();
for (Collection<Change> changeCollection : map.values()) {
changes.addAll(changeCollection);
}
if (! changes.isEmpty()) {
final ShelvedChangeList list = GitShelveUtils.shelveChanges(myProject, myShelveManager, changes,
myStashMessage + " [" + entry.getKey() + "]", exceptions, false);
myShelvedLists.put(entry.getKey(), list);
}
}
if (! exceptions.isEmpty()) {
LOG.info("save " + exceptions, exceptions.get(0));
myShelvedLists = null; // no restore here since during shelving changes are not rolled back...
throw exceptions.get(0);
} else {
for (VirtualFile root : rootsToSave) {
GitRollbackEnvironment.resetHardLocal(myProject, root);
}
}
myProgressIndicator.setText(oldProgressTitle);
}
protected void load(ContinuationContext context) {
if (myShelvedChangeList != null) {
if (myShelvedLists != null) {
LOG.info("load ");
String oldProgressTitle = myProgressIndicator.getText();
myProgressIndicator.setText(GitBundle.getString("update.unshelving.changes"));
if (myShelvedChangeList != null) {
GitShelveUtils.doSystemUnshelve(myProject, myShelvedChangeList, myShelveManager, context);
if (myShelvedLists != null) {
for (ShelvedChangeList list : myShelvedLists.values()) {
GitShelveUtils.doSystemUnshelve(myProject, list, myShelveManager, context);
}
}
myProgressIndicator.setText(oldProgressTitle);
}
@@ -87,7 +98,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
@Override
protected boolean wereChangesSaved() {
return myShelvedChangeList != null;
return myShelvedLists != null;
}
@Override
@@ -97,7 +108,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
@Override
protected void showSavedChanges() {
myShelveViewManager.activateView(myShelvedChangeList);
myShelveViewManager.activateView(myShelvedLists.get(myShelvedLists.keySet().iterator().next()));
}
@Override