IDEA-86665 hg annotate: ignore whitespace changes

*option to ignore whitespace differences in annotations added to mercurial configuration panel;
*annotate with ignored whitespace option if supported;
*supported version added;
*tests added
This commit is contained in:
Nadya Zabrodina
2014-04-18 16:40:04 +04:00
parent 6e551bafeb
commit e6d5ea60e8
7 changed files with 80 additions and 10 deletions
@@ -55,6 +55,8 @@ hg4idea.unable.to.run.hg=Unable to run hg: {0}
hg4idea.run.success.title=Hg Executed Successfully
hg4idea.run.failed.title=Hg Execution Failed
hg4idea.configuration.ignore.whitespace.in.annotate=Ignore &whitespace differences in annotations
hg4idea.command.executable.error=Error executing \"{0}\". Make sure you have setup the right executable in Mercurial configuration
hg4idea.commit.success=Repository \"{0}\" committed
@@ -16,6 +16,8 @@ import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.VcsAnnotationRefresher;
import org.jetbrains.annotations.NotNull;
@State(
@@ -23,11 +25,14 @@ import org.jetbrains.annotations.NotNull;
storages = @Storage(file = StoragePathMacros.WORKSPACE_FILE)
)
public class HgProjectSettings implements PersistentStateComponent<HgProjectSettings.State> {
@NotNull private final HgGlobalSettings myAppSettings;
@NotNull private final HgGlobalSettings myAppSettings;
@NotNull private final Project myProject;
private State myState = new State();
public HgProjectSettings(@NotNull HgGlobalSettings appSettings) {
public HgProjectSettings(@NotNull Project project, @NotNull HgGlobalSettings appSettings) {
myProject = project;
myAppSettings = appSettings;
}
@@ -35,6 +40,7 @@ public class HgProjectSettings implements PersistentStateComponent<HgProjectSett
public boolean myCheckIncoming = true;
public boolean myCheckOutgoing = true;
public Boolean CHECK_INCOMING_OUTGOING = null;
public boolean myIgnoreWhitespacesInAnnotations = true;
}
public State getState() {
@@ -52,10 +58,22 @@ public class HgProjectSettings implements PersistentStateComponent<HgProjectSett
return myState.CHECK_INCOMING_OUTGOING != null && myState.CHECK_INCOMING_OUTGOING.booleanValue();
}
public boolean isWhitespacesIgnoredInAnnotations() {
return myState.myIgnoreWhitespacesInAnnotations;
}
public void setCheckIncomingOutgoing(boolean checkIncomingOutgoing) {
myState.CHECK_INCOMING_OUTGOING = checkIncomingOutgoing;
}
public void setIgnoreWhitespacesInAnnotations(boolean ignoreWhitespacesInAnnotations) {
final boolean changed = myState.myIgnoreWhitespacesInAnnotations != ignoreWhitespacesInAnnotations;
myState.myIgnoreWhitespacesInAnnotations = ignoreWhitespacesInAnnotations;
if (changed) {
myProject.getMessageBus().syncPublisher(VcsAnnotationRefresher.LOCAL_CHANGES_CHANGED).configurationChanged(HgVcs.getKey());
}
}
public String getHgExecutable() {
return myAppSettings.getHgExecutable();
}
@@ -19,6 +19,7 @@ import com.intellij.util.text.DateFormatUtil;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.HgFile;
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.provider.annotate.HgAnnotationLine;
@@ -55,6 +56,12 @@ public class HgAnnotateCommand {
public List<HgAnnotationLine> execute(@NotNull HgFile hgFile, VcsFileRevision revision) {
final List<String> arguments = new ArrayList<String>();
arguments.add("-cvnudl");
HgVcs vcs = HgVcs.getInstance(myProject);
if (vcs != null &&
vcs.getProjectSettings().isWhitespacesIgnoredInAnnotations() &&
vcs.getVersion().isIgnoreWhitespaceDiffInAnnotationsSupported()) {
arguments.add("-w");
}
if (revision != null) {
arguments.add("-r");
HgRevisionNumber revisionNumber = (HgRevisionNumber)revision.getRevisionNumber();
@@ -8,7 +8,7 @@
<properties/>
<border type="none"/>
<children>
<grid id="8c1f" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="8c1f" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
@@ -28,6 +28,15 @@
<text value="Check for &amp;incoming and outgoing changesets"/>
</properties>
</component>
<component id="36003" class="javax.swing.JCheckBox" binding="myIgnoredWhitespacesInAnnotationsCbx">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text resource-bundle="org/zmlx/hg4idea/HgVcsMessages" key="hg4idea.configuration.ignore.whitespace.in.annotate"/>
</properties>
</component>
</children>
</grid>
<grid id="4e3f3" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -33,6 +33,7 @@ public class HgConfigurationProjectPanel {
private JPanel myMainPanel;
private JCheckBox myCheckIncomingOutgoingCbx;
private JCheckBox myIgnoredWhitespacesInAnnotationsCbx;
private TextFieldWithBrowseButton myPathSelector;
private JButton myTestButton;
private final HgVcs myVcs;
@@ -61,11 +62,14 @@ public class HgConfigurationProjectPanel {
public boolean isModified() {
boolean executableModified = !getCurrentPath().equals(myProjectSettings.getHgExecutable());
return executableModified || myCheckIncomingOutgoingCbx.isSelected() != myProjectSettings.isCheckIncomingOutgoing();
return executableModified ||
myCheckIncomingOutgoingCbx.isSelected() != myProjectSettings.isCheckIncomingOutgoing() ||
myIgnoredWhitespacesInAnnotationsCbx.isSelected() != myProjectSettings.isWhitespacesIgnoredInAnnotations();
}
public void saveSettings() {
myProjectSettings.setCheckIncomingOutgoing(myCheckIncomingOutgoingCbx.isSelected());
myProjectSettings.setIgnoreWhitespacesInAnnotations(myIgnoredWhitespacesInAnnotationsCbx.isSelected());
myProjectSettings.setHgExecutable(getCurrentPath());
myVcs.checkVersion();
}
@@ -75,7 +79,8 @@ public class HgConfigurationProjectPanel {
}
public void loadSettings() {
myCheckIncomingOutgoingCbx.setSelected(myProjectSettings.isCheckIncomingOutgoing() );
myCheckIncomingOutgoingCbx.setSelected(myProjectSettings.isCheckIncomingOutgoing());
myIgnoredWhitespacesInAnnotationsCbx.setSelected(myProjectSettings.isWhitespacesIgnoredInAnnotations());
myPathSelector.setText(myProjectSettings.getGlobalSettings().getHgExecutable());
}
@@ -56,6 +56,7 @@ public final class HgVersion implements Comparable<HgVersion> {
public static final HgVersion PARENT_REVISION_TEMPLATES_SUPPORTED = new HgVersion(2, 4, 0);
public static final HgVersion BRANCH_HEADS_BASE_SERVED_FILE_EXIST = new HgVersion(2, 5, 0);
public static final HgVersion BRANCH2_FILE_EXIST = new HgVersion(2, 9, 0);
public static final HgVersion IGNORE_WHITESPACE_DIFF_IN_ANNOTATIONS = new HgVersion(2, 1, 0);
//see http://selenic.com/pipermail/mercurial-devel/2013-May/051209.html fixed since 2.7
private static final HgVersion LARGEFILES_WITH_FOLLOW_SUPPORTED = new HgVersion(2, 7, 0);
@@ -163,6 +164,10 @@ public final class HgVersion implements Comparable<HgVersion> {
return compareTo(PARENT_REVISION_TEMPLATES_SUPPORTED) >= 0;
}
public boolean isIgnoreWhitespaceDiffInAnnotationsSupported() {
return compareTo(IGNORE_WHITESPACE_DIFF_IN_ANNOTATIONS) >= 0;
}
public boolean hasBranchHeadsBaseServed() {
return compareTo(BRANCH_HEADS_BASE_SERVED_FILE_EXIST) >= 0 && compareTo(BRANCH2_FILE_EXIST) < 0;
}
@@ -14,13 +14,9 @@ import java.util.Arrays;
import java.util.Date;
import java.util.List;
import static com.intellij.openapi.vcs.Executor.cd;
import static com.intellij.openapi.vcs.Executor.echo;
import static com.intellij.openapi.vcs.Executor.*;
import static hg4idea.test.HgExecutor.hg;
/**
* @author Nadya Zabrodina
*/
public class HgAnnotationTest extends HgPlatformTest {
String firstCreatedFile = "file.txt";
static final String author1 = "a.bacaba@jetbrains.com";
@@ -53,4 +49,32 @@ public class HgAnnotationTest extends HgPlatformTest {
assertEquals(date, line.get(HgAnnotation.FIELD.DATE));
}
}
public void testAnnotationWithIgnoredWhitespaces() {
annotationWithWhitespaceOption(true);
}
public void testAnnotationWithoutIgnoredWhitespaces() {
annotationWithWhitespaceOption(false);
}
private void annotationWithWhitespaceOption(boolean ignoreWhitespaces) {
cd(myRepository);
String whitespaceFile = "whitespaces.txt";
touch(whitespaceFile, "not whitespaces");
myRepository.refresh(false, true);
String whiteSpaceAuthor = "Mr.Whitespace";
final VirtualFile file = myRepository.findFileByRelativePath(whitespaceFile);
assert file != null;
hg("add " + whitespaceFile);
hg("commit -m modify -u '" + defaultAuthor + "'");
echo(whitespaceFile, " ");//add several whitespaces
hg("commit -m whitespaces -u '" + whiteSpaceAuthor + "'");
final HgFile hgFile = new HgFile(myRepository, VfsUtilCore.virtualToIoFile(file));
myVcs.getProjectSettings().setIgnoreWhitespacesInAnnotations(ignoreWhitespaces);
List<HgAnnotationLine> annotationLines =
new HgAnnotateCommand(myProject).execute(hgFile, null);
HgAnnotationLine line = annotationLines.get(0);
assertEquals(ignoreWhitespaces ? defaultAuthor : whiteSpaceAuthor, line.get(HgAnnotation.FIELD.USER));
}
}