[hg]: rename field and getter for moved files, because we actually collect only renamed/moved, not copied; improve file statuses

This commit is contained in:
Nadya Zabrodina
2016-03-26 12:51:40 +03:00
parent 5bdcc99e18
commit 7b242dd3e3
4 changed files with 33 additions and 26 deletions
@@ -38,11 +38,11 @@ public class HgFileRevision implements VcsFileRevision {
private final Set<String> myFilesModified;
private final Set<String> myFilesAdded;
private final Set<String> myFilesDeleted;
private final Map<String, String> myFilesCopied;
private final Map<String, String> myFilesMoved; // actually we collect moved and track copied as added
public HgFileRevision(Project project, @NotNull HgFile hgFile, @NotNull HgRevisionNumber vcsRevisionNumber,
String branchName, Date revisionDate, String author, String commitMessage,
Set<String> filesModified, Set<String> filesAdded, Set<String> filesDeleted, Map<String, String> filesCopied) {
Set<String> filesModified, Set<String> filesAdded, Set<String> filesDeleted, Map<String, String> filesMoved) {
myProject = project;
myFile = hgFile;
myRevisionNumber = vcsRevisionNumber;
@@ -53,7 +53,7 @@ public class HgFileRevision implements VcsFileRevision {
myFilesModified = filesModified;
myFilesAdded = filesAdded;
myFilesDeleted = filesDeleted;
myFilesCopied = filesCopied;
myFilesMoved = filesMoved;
}
@NotNull
@@ -101,8 +101,8 @@ public class HgFileRevision implements VcsFileRevision {
}
@NotNull
public Map<String, String> getCopiedFiles() {
return myFilesCopied;
public Map<String, String> getMovedFiles() {
return myFilesMoved;
}
@NotNull
@@ -43,6 +43,7 @@ import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.*;
import org.zmlx.hg4idea.command.HgLogCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.provider.HgChangeProvider;
import org.zmlx.hg4idea.util.HgChangesetUtil;
import org.zmlx.hg4idea.util.HgUtil;
import org.zmlx.hg4idea.util.HgVersion;
@@ -163,9 +164,9 @@ public class HgHistoryUtil {
for (String file : revision.getDeletedFiles()) {
changes.add(createChange(project, root, file, firstParent, null, vcsRevisionNumber, FileStatus.DELETED));
}
for (Map.Entry<String, String> copiedFile : revision.getCopiedFiles().entrySet()) {
changes
.add(createChange(project, root, copiedFile.getKey(), firstParent, copiedFile.getValue(), vcsRevisionNumber, FileStatus.ADDED));
for (Map.Entry<String, String> copiedFile : revision.getMovedFiles().entrySet()) {
changes.add(createChange(project, root, copiedFile.getKey(), firstParent, copiedFile.getValue(), vcsRevisionNumber,
HgChangeProvider.RENAMED));
}
vcsFullCommitDetailsList.add(factory.createFullDetails(factory.createHash(vcsRevisionNumber.getChangeset()), parentsHash,
@@ -240,8 +240,9 @@ public class HgCachingCommittedChangesProvider implements CachingCommittedChange
for (String file : revision.getDeletedFiles()) {
changes.add(createChange(root, file, firstParent, null, vcsRevisionNumber, FileStatus.DELETED));
}
for (Map.Entry<String, String> copiedFile : revision.getCopiedFiles().entrySet()) {
changes.add(createChange(root, copiedFile.getKey(), firstParent, copiedFile.getValue(), vcsRevisionNumber, FileStatus.ADDED));
for (Map.Entry<String, String> copiedFile : revision.getMovedFiles().entrySet()) {
changes
.add(createChange(root, copiedFile.getKey(), firstParent, copiedFile.getValue(), vcsRevisionNumber, HgChangeProvider.RENAMED));
}
result.add(new HgCommittedChangeList(myVcs, vcsRevisionNumber, revision.getBranchName(), revision.getCommitMessage(),
@@ -352,8 +353,8 @@ public class HgCachingCommittedChangesProvider implements CachingCommittedChange
for (String file : localRevision.getDeletedFiles()) {
changes.add(createChange(root, file, firstParent, null, vcsRevisionNumber, FileStatus.DELETED));
}
for (Map.Entry<String, String> copiedFile : localRevision.getCopiedFiles().entrySet()) {
changes.add(createChange(root, copiedFile.getKey(), firstParent, copiedFile.getValue(), vcsRevisionNumber, HgChangeProvider.COPIED));
for (Map.Entry<String, String> copiedFile : localRevision.getMovedFiles().entrySet()) {
changes.add(createChange(root, copiedFile.getKey(), firstParent, copiedFile.getValue(), vcsRevisionNumber, HgChangeProvider.RENAMED));
}
return new HgCommittedChangeList(myVcs, vcsRevisionNumber, localRevision.getBranchName(), localRevision.getCommitMessage(),
@@ -88,7 +88,7 @@ public class HgHistoryProvider implements VcsHistoryProvider {
final List<HgFileRevision> history = getHistory(filePath, vcsRoot, myProject);
if (history.size() == 0) return;
final VcsAbstractHistorySession emptySession = createAppendableSession(vcsRoot, Collections.<VcsFileRevision>emptyList(), null);
final VcsAbstractHistorySession emptySession = createAppendableSession(vcsRoot, Collections.emptyList(), null);
partner.reportCreatedEmptySession(emptySession);
for (HgFileRevision hgFileRevision : history) {
@@ -126,12 +126,21 @@ public class HgHistoryProvider implements VcsHistoryProvider {
@NotNull VirtualFile vcsRoot,
@NotNull Project project,
@Nullable HgRevisionNumber revisionNumber, int limit) {
final HgFile hgFile = new HgFile(vcsRoot, filePath);
FilePath originalFileName = HgUtil.getOriginalFileName(hgFile.toFilePath(), ChangeListManager.getInstance(project));
HgFile originalHgFile = new HgFile(hgFile.getRepo(), originalFileName);
if (revisionNumber == null && !filePath.isDirectory() && !originalHgFile.toFilePath().equals(hgFile.toFilePath())) {
/* The standard way to get history following renames is to call hg log --follow. However:
1. It is broken in case of uncommitted rename (i.e. if the file is currently renamed in the working dir):
in this case we use a special python template "follow(path)" which handles this case.
2. We don't use this python "follow(path)" function for all cases, because it is fully supported only since hg 2.6,
and it is a bit slower and possibly less reliable than plain --follow parameter.
3. It doesn't work with "-r": in this case --follow is simply ignored (hg commit 24208:8b4b9ee6001a).
As a workaround we could use the same follow(path) python, but this function requires current name of the file,
which is unknown in case of "-r", and identifying it would be very slow.
As a result we don't follow renames in annotate called from diff or from an old revision, which we can survive.
*/
FilePath originalFilePath = HgUtil.getOriginalFileName(filePath, ChangeListManager.getInstance(project));
if (revisionNumber == null && !filePath.isDirectory() && !filePath.equals(originalFilePath)) {
// uncommitted renames detected
return getHistoryForUncommittedRenamed(originalHgFile, vcsRoot, project, limit);
return getHistoryForUncommittedRenamed(originalFilePath, vcsRoot, project, limit);
}
final HgLogCommand logCommand = new HgLogCommand(project);
logCommand.setFollowCopies(!filePath.isDirectory());
@@ -139,22 +148,18 @@ public class HgHistoryProvider implements VcsHistoryProvider {
List<String> args = new ArrayList<String>();
if (revisionNumber != null) {
args.add("--rev");
args.add("reverse(0::" + revisionNumber.getChangeset() + ")");// hg ignors --follow if --rev presented
// reverse needed because of mercurial default order problem -r rev set with and without -f option
args.add("reverse(0::" + revisionNumber.getChangeset() + ")");
}
return logCommand.execute(hgFile, limit, false, args);
return logCommand.execute(new HgFile(vcsRoot, filePath), limit, false, args);
}
/**
* Workaround for getting follow file history in case of uncommitted move/rename change
*/
private static List<HgFileRevision> getHistoryForUncommittedRenamed(@NotNull HgFile originalHgFile,
private static List<HgFileRevision> getHistoryForUncommittedRenamed(@NotNull FilePath originalHgFilePath,
@NotNull VirtualFile vcsRoot,
@NotNull Project project, int limit) {
//mercurial can't follow custom revision;
// the only way to do it if you have working dir file name then use python follow function for it,
// but we have to use local(last committed) name as a parameter
HgFile originalHgFile = new HgFile(vcsRoot, originalHgFilePath);
final HgLogCommand logCommand = new HgLogCommand(project);
logCommand.setIncludeRemoved(true);
final HgVersion version = logCommand.getVersion();