Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2021-04-29 13:39:15 +0000
committerMatthias Sohn2021-06-01 10:32:05 +0000
commitaaed129d046863f4c76aa64beee211df594789e1 (patch)
tree254ee9319df9536ae216e479ad66af9c1d5e8444
parent5996134fd793388bf747052023bf9ffacab21072 (diff)
downloadegit-aaed129d046863f4c76aa64beee211df594789e1.tar.gz
egit-aaed129d046863f4c76aa64beee211df594789e1.tar.xz
egit-aaed129d046863f4c76aa64beee211df594789e1.zip
[merge] Hide changes between ancestor and current for cherry-pick
By default hide these changes. The ancestor in a cherry-pick is a parent commit of 'theirs' (the commit that was cherry-picked); the differences between that parent and the current version are simply not interesting and even misleading. Add an action to the content merge viewer's toolbar to allow the user to toggle this setting for three-way comparisons. Bug: 441149 Change-Id: I154cbecd445ef4481a1288c87c0e6e9cf498651f Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_left.svg299
-rw-r--r--icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_right.svg299
-rw-r--r--org.eclipse.egit.ui/icons/etool16/merge_ignore_left.pngbin0 -> 550 bytes
-rw-r--r--org.eclipse.egit.ui/icons/etool16/merge_ignore_left@2x.pngbin0 -> 1166 bytes
-rw-r--r--org.eclipse.egit.ui/icons/etool16/merge_ignore_right.pngbin0 -> 555 bytes
-rw-r--r--org.eclipse.egit.ui/icons/etool16/merge_ignore_right@2x.pngbin0 -> 1186 bytes
-rw-r--r--org.eclipse.egit.ui/plugin.properties2
-rw-r--r--org.eclipse.egit.ui/plugin.xml6
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java14
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/CompareEditorInputViewerAction.java105
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java129
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeDiffNode.java45
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/ToggleCurrentChangesAction.java164
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/NotifiableDiffNode.java33
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties1
16 files changed, 1091 insertions, 9 deletions
diff --git a/icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_left.svg b/icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_left.svg
new file mode 100644
index 0000000000..341efe91cc
--- /dev/null
+++ b/icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_left.svg
@@ -0,0 +1,299 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<!-- Base image from org.eclipse.compare, elcl16, ancestorpane_co.svg -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="merge_ignore_left.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient4452"
+ inkscape:collect="always">
+ <stop
+ id="stop4454"
+ offset="0"
+ style="stop-color:#d5f3ff;stop-opacity:1" />
+ <stop
+ id="stop4456"
+ offset="1"
+ style="stop-color:#edfaff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4380"
+ inkscape:collect="always">
+ <stop
+ id="stop4382"
+ offset="0"
+ style="stop-color:#6f94bf;stop-opacity:1" />
+ <stop
+ id="stop4384"
+ offset="1"
+ style="stop-color:#4476aa;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4374"
+ inkscape:collect="always">
+ <stop
+ id="stop4376"
+ offset="0"
+ style="stop-color:#6fb6e2;stop-opacity:1" />
+ <stop
+ id="stop4378"
+ offset="1"
+ style="stop-color:#cee3f3;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4333">
+ <stop
+ style="stop-color:#c6e26e;stop-opacity:1"
+ offset="0"
+ id="stop4335" />
+ <stop
+ style="stop-color:#fafcf4;stop-opacity:1"
+ offset="1"
+ id="stop4337" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4288">
+ <stop
+ style="stop-color:#8a97ac;stop-opacity:1"
+ offset="0"
+ id="stop4290" />
+ <stop
+ style="stop-color:#bfb688;stop-opacity:1"
+ offset="1"
+ id="stop4292" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4288"
+ id="linearGradient4294"
+ x1="688.31909"
+ y1="317.17447"
+ x2="688.31909"
+ y2="274.16879"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-53.757103,-5.9194102e-6)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4333"
+ id="linearGradient4339"
+ x1="666.81628"
+ y1="267.00119"
+ x2="713.40576"
+ y2="299.25543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-53.757103,-5.9194102e-6)" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.14285703,-53.757195,227.32227)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4374"
+ id="linearGradient4339-8"
+ x1="666.81641"
+ y1="277.75256"
+ x2="713.40576"
+ y2="299.25543"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.14285703,-53.757195,227.32227)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4380"
+ id="linearGradient4294-5"
+ x1="713.40582"
+ y1="327.92587"
+ x2="666.81641"
+ y2="327.92587"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,278.75515,225.27333)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4452"
+ id="linearGradient4339-9"
+ x1="668.60834"
+ y1="271.48099"
+ x2="697.27881"
+ y2="296.56766"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,278.75515,225.27333)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4288"
+ id="linearGradient4294-4"
+ x1="688.31909"
+ y1="317.17447"
+ x2="690.11121"
+ y2="183.67766"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,303.84175,225.27334)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4452"
+ id="linearGradient4339-9-9"
+ x1="668.6084"
+ y1="271.48096"
+ x2="697.27887"
+ y2="296.56763"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,303.84175,225.27334)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4288"
+ id="linearGradient4294-4-9"
+ x1="688.31909"
+ y1="317.17447"
+ x2="690.11127"
+ y2="183.67761"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(1.6915432,0,0,1.691535,609.22181,-1467.265)"
+ gradientUnits="userSpaceOnUse"
+ y2="1038.5814"
+ x2="4.7528968"
+ y1="1051.0466"
+ x1="4.7528968"
+ id="x-bg"
+ xlink:href="#x-bg-3"
+ inkscape:collect="always" />
+ <linearGradient
+ id="x-bg-3"
+ inkscape:collect="always">
+ <stop
+ id="x-bg-stop0"
+ offset="0"
+ style="stop-color:#df2c33;stop-opacity:1" />
+ <stop
+ id="x-bg-stop1"
+ offset="1"
+ style="stop-color:#f5817d;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(1.6915432,0,0,1.691535,609.22181,-1467.265)"
+ gradientUnits="userSpaceOnUse"
+ y2="1037.7"
+ x2="8.6566515"
+ y1="1050.7386"
+ x1="8.6566515"
+ id="x-stroke"
+ xlink:href="#x-stroke-6"
+ inkscape:collect="always" />
+ <linearGradient
+ id="x-stroke-6"
+ inkscape:collect="always">
+ <stop
+ id="x-stroke-stop0"
+ offset="0"
+ style="stop-color:#c51325;stop-opacity:1;" />
+ <stop
+ id="x-stroke-stop1"
+ offset="1"
+ style="stop-color:#ca5d49;stop-opacity:1" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="34.206291"
+ inkscape:cx="15.940528"
+ inkscape:cy="8.2561974"
+ inkscape:document-units="px"
+ inkscape:current-layer="g8667"
+ showgrid="true"
+ inkscape:window-width="2341"
+ inkscape:window-height="1019"
+ inkscape:window-x="65"
+ inkscape:window-y="322"
+ inkscape:window-maximized="0"
+ inkscape:snap-global="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3032" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline"
+ transform="translate(0,-1036.3622)">
+ <g
+ id="g8667"
+ transform="matrix(0.27903303,0,0,0.27903303,-169.06377,963.86005)">
+ <rect
+ style="opacity:1;fill:url(#linearGradient4339);fill-opacity:1;stroke:url(#linearGradient4294);stroke-width:3.58380508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286"
+ width="50.173248"
+ height="50.173267"
+ x="611.26733"
+ y="265.20929" />
+ <rect
+ style="display:inline;opacity:1;fill:url(#linearGradient4339-8);fill-opacity:1;stroke:url(#linearGradient4294-5);stroke-width:3.58380508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286-8"
+ width="50.173248"
+ height="7.1676044"
+ x="611.26733"
+ y="265.20929" />
+ <rect
+ style="display:inline;opacity:1;fill:url(#linearGradient4339-9);fill-opacity:1;stroke:url(#linearGradient4294-4);stroke-width:3.58380532;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286-9"
+ width="25.086613"
+ height="14.335201"
+ x="611.26733"
+ y="301.04733" />
+ <rect
+ style="display:inline;opacity:1;fill:url(#linearGradient4339-9-9);fill-opacity:1;stroke:url(#linearGradient4294-4-9);stroke-width:3.58380508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286-9-4"
+ width="25.086613"
+ height="14.335201"
+ x="636.35394"
+ y="301.04733" />
+ <path
+ sodipodi:nodetypes="sccccccccssccsccsccss"
+ inkscape:connector-curvature="0"
+ id="x-0"
+ d="m 631.92114,289.65672 c -0.79196,-0.79166 -2.06703,-0.79166 -2.85894,0 l -5.26543,5.26605 -5.26539,-5.26605 c -0.79184,-0.79166 -2.06703,-0.79166 -2.85894,0 l -1.45482,1.45467 c -0.79188,0.79238 -0.79186,2.0675 6e-5,2.85952 l 5.26531,5.26532 -5.26532,5.26497 c -0.79199,0.79202 -0.79197,2.06714 -2e-5,2.85916 l 1.4549,1.45431 c 0.79186,0.79274 2.06694,0.79274 2.85894,0 l 5.26539,-5.26497 5.30199,5.30188 c 0.79187,0.79274 2.06694,0.79274 2.85894,0 l 1.45481,-1.4543 c 0.79192,-0.79203 0.78396,-2.05926 -5e-5,-2.85881 l -5.30199,-5.30224 5.2654,-5.26532 c 0.79194,-0.79202 0.79192,-2.06714 5e-5,-2.85952 z"
+ style="display:inline;fill:url(#x-bg);fill-opacity:1;stroke:url(#x-stroke);stroke-width:1.65872896;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1">
+ <title
+ id="title3202-1">x</title>
+ </path>
+ </g>
+ <g
+ transform="translate(-20.000002,2.6171874e-6)"
+ style="stroke:#694337;stroke-opacity:1;display:inline"
+ id="g11029" />
+ </g>
+</svg>
diff --git a/icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_right.svg b/icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_right.svg
new file mode 100644
index 0000000000..1e28b1e7c5
--- /dev/null
+++ b/icons/org.eclipse.egit.ui/icons/etool16/merge_ignore_right.svg
@@ -0,0 +1,299 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<!-- Base image from org.eclipse.compare, elcl16, ancestorpane_co.svg -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="merge_ignore_right.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient4452"
+ inkscape:collect="always">
+ <stop
+ id="stop4454"
+ offset="0"
+ style="stop-color:#d5f3ff;stop-opacity:1" />
+ <stop
+ id="stop4456"
+ offset="1"
+ style="stop-color:#edfaff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4380"
+ inkscape:collect="always">
+ <stop
+ id="stop4382"
+ offset="0"
+ style="stop-color:#6f94bf;stop-opacity:1" />
+ <stop
+ id="stop4384"
+ offset="1"
+ style="stop-color:#4476aa;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4374"
+ inkscape:collect="always">
+ <stop
+ id="stop4376"
+ offset="0"
+ style="stop-color:#6fb6e2;stop-opacity:1" />
+ <stop
+ id="stop4378"
+ offset="1"
+ style="stop-color:#cee3f3;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4333">
+ <stop
+ style="stop-color:#c6e26e;stop-opacity:1"
+ offset="0"
+ id="stop4335" />
+ <stop
+ style="stop-color:#fafcf4;stop-opacity:1"
+ offset="1"
+ id="stop4337" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4288">
+ <stop
+ style="stop-color:#8a97ac;stop-opacity:1"
+ offset="0"
+ id="stop4290" />
+ <stop
+ style="stop-color:#bfb688;stop-opacity:1"
+ offset="1"
+ id="stop4292" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4288"
+ id="linearGradient4294"
+ x1="688.31909"
+ y1="317.17447"
+ x2="688.31909"
+ y2="274.16879"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-53.757103,-5.9194102e-6)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4333"
+ id="linearGradient4339"
+ x1="666.81628"
+ y1="267.00119"
+ x2="713.40576"
+ y2="299.25543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-53.757103,-5.9194102e-6)" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.14285703,-53.757195,227.32227)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4374"
+ id="linearGradient4339-8"
+ x1="666.81641"
+ y1="277.75256"
+ x2="713.40576"
+ y2="299.25543"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.14285703,-53.757195,227.32227)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4380"
+ id="linearGradient4294-5"
+ x1="713.40582"
+ y1="327.92587"
+ x2="666.81641"
+ y2="327.92587"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,278.75515,225.27333)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4452"
+ id="linearGradient4339-9"
+ x1="668.60834"
+ y1="271.48099"
+ x2="697.27881"
+ y2="296.56766"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,278.75515,225.27333)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4288"
+ id="linearGradient4294-4"
+ x1="688.31909"
+ y1="317.17447"
+ x2="690.11121"
+ y2="183.67766"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,303.84175,225.27334)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4452"
+ id="linearGradient4339-9-9"
+ x1="668.6084"
+ y1="271.48096"
+ x2="697.27887"
+ y2="296.56763"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.4999998,0,0,0.28571392,303.84175,225.27334)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient4288"
+ id="linearGradient4294-4-9"
+ x1="688.31909"
+ y1="317.17447"
+ x2="690.11127"
+ y2="183.67761"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(1.6915432,0,0,1.691535,634.30844,-1467.265)"
+ gradientUnits="userSpaceOnUse"
+ y2="1038.5814"
+ x2="4.7528968"
+ y1="1051.0466"
+ x1="4.7528968"
+ id="x-bg"
+ xlink:href="#x-bg-3"
+ inkscape:collect="always" />
+ <linearGradient
+ id="x-bg-3"
+ inkscape:collect="always">
+ <stop
+ id="x-bg-stop0"
+ offset="0"
+ style="stop-color:#df2c33;stop-opacity:1" />
+ <stop
+ id="x-bg-stop1"
+ offset="1"
+ style="stop-color:#f5817d;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(1.6915432,0,0,1.691535,634.30844,-1467.265)"
+ gradientUnits="userSpaceOnUse"
+ y2="1037.7"
+ x2="8.6566515"
+ y1="1050.7386"
+ x1="8.6566515"
+ id="x-stroke"
+ xlink:href="#x-stroke-6"
+ inkscape:collect="always" />
+ <linearGradient
+ id="x-stroke-6"
+ inkscape:collect="always">
+ <stop
+ id="x-stroke-stop0"
+ offset="0"
+ style="stop-color:#c51325;stop-opacity:1;" />
+ <stop
+ id="x-stroke-stop1"
+ offset="1"
+ style="stop-color:#ca5d49;stop-opacity:1" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="34.206291"
+ inkscape:cx="9.0265951"
+ inkscape:cy="8.2561974"
+ inkscape:document-units="px"
+ inkscape:current-layer="g8667"
+ showgrid="true"
+ inkscape:window-width="2341"
+ inkscape:window-height="1019"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
+ inkscape:snap-global="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3032" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline"
+ transform="translate(0,-1036.3622)">
+ <g
+ id="g8667"
+ transform="matrix(0.27903303,0,0,0.27903303,-169.06377,963.86005)">
+ <rect
+ style="opacity:1;fill:url(#linearGradient4339);fill-opacity:1;stroke:url(#linearGradient4294);stroke-width:3.58380508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286"
+ width="50.173248"
+ height="50.173267"
+ x="611.26733"
+ y="265.20929" />
+ <rect
+ style="display:inline;opacity:1;fill:url(#linearGradient4339-8);fill-opacity:1;stroke:url(#linearGradient4294-5);stroke-width:3.58380508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286-8"
+ width="50.173248"
+ height="7.1676044"
+ x="611.26733"
+ y="265.20929" />
+ <rect
+ style="display:inline;opacity:1;fill:url(#linearGradient4339-9);fill-opacity:1;stroke:url(#linearGradient4294-4);stroke-width:3.58380532;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286-9"
+ width="25.086613"
+ height="14.335201"
+ x="611.26733"
+ y="301.04733" />
+ <rect
+ style="display:inline;opacity:1;fill:url(#linearGradient4339-9-9);fill-opacity:1;stroke:url(#linearGradient4294-4-9);stroke-width:3.58380508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4286-9-4"
+ width="25.086613"
+ height="14.335201"
+ x="636.35394"
+ y="301.04733" />
+ <path
+ sodipodi:nodetypes="sccccccccssccsccsccss"
+ inkscape:connector-curvature="0"
+ id="x-0"
+ d="m 657.00777,289.65672 c -0.79196,-0.79166 -2.06703,-0.79166 -2.85894,0 l -5.26543,5.26605 -5.26539,-5.26605 c -0.79184,-0.79166 -2.06703,-0.79166 -2.85894,0 l -1.45482,1.45467 c -0.79188,0.79238 -0.79186,2.0675 6e-5,2.85952 l 5.26531,5.26532 -5.26532,5.26497 c -0.79199,0.79202 -0.79197,2.06714 -2e-5,2.85916 l 1.4549,1.45431 c 0.79186,0.79274 2.06694,0.79274 2.85894,0 l 5.26539,-5.26497 5.30199,5.30188 c 0.79187,0.79274 2.06694,0.79274 2.85894,0 l 1.45481,-1.4543 c 0.79192,-0.79203 0.78396,-2.05926 -5e-5,-2.85881 l -5.30199,-5.30224 5.2654,-5.26532 c 0.79194,-0.79202 0.79192,-2.06714 5e-5,-2.85952 z"
+ style="display:inline;fill:url(#x-bg);fill-opacity:1;stroke:url(#x-stroke);stroke-width:1.65872896;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1">
+ <title
+ id="title3202-1">x</title>
+ </path>
+ </g>
+ <g
+ transform="translate(-20.000002,2.6171874e-6)"
+ style="stroke:#694337;stroke-opacity:1;display:inline"
+ id="g11029" />
+ </g>
+</svg>
diff --git a/org.eclipse.egit.ui/icons/etool16/merge_ignore_left.png b/org.eclipse.egit.ui/icons/etool16/merge_ignore_left.png
new file mode 100644
index 0000000000..8367213714
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/etool16/merge_ignore_left.png
Binary files differ
diff --git a/org.eclipse.egit.ui/icons/etool16/merge_ignore_left@2x.png b/org.eclipse.egit.ui/icons/etool16/merge_ignore_left@2x.png
new file mode 100644
index 0000000000..123a3196a4
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/etool16/merge_ignore_left@2x.png
Binary files differ
diff --git a/org.eclipse.egit.ui/icons/etool16/merge_ignore_right.png b/org.eclipse.egit.ui/icons/etool16/merge_ignore_right.png
new file mode 100644
index 0000000000..d6fb17279a
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/etool16/merge_ignore_right.png
Binary files differ
diff --git a/org.eclipse.egit.ui/icons/etool16/merge_ignore_right@2x.png b/org.eclipse.egit.ui/icons/etool16/merge_ignore_right@2x.png
new file mode 100644
index 0000000000..847c92673f
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/etool16/merge_ignore_right@2x.png
Binary files differ
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index 8b2f768bc9..af3d7a5176 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -401,6 +401,8 @@ ShowUnifiedDiffCommand.name = Show Unified Diff
DiffViewerContext = In Diff Viewer
UnifiedDiffQuickOutlineCommand.name = Quick Outline
UnifiedDiffQuickOutlineCommand.description = Show the quick outline for a unified diff
+ToggleCurrentChangesCommand.name = Ignore Changes from Ancestor to Current Version
+ToggleCurrentChangesCommand.description = Toggle ignoring changes only between the ancestor and the current version in a three-way merge comparison
FetchFromGerritCommand.name = Fetch From Gerrit
FetchFromGerritCommand.label = Fetch from &Gerrit...
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index fc38e2a02c..61d5a3325f 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -1166,6 +1166,12 @@
name="%UnifiedDiffQuickOutlineCommand.name"
description="%UnifiedDiffQuickOutlineCommand.description">
</command>
+ <command
+ categoryId="org.eclipse.egit.ui.commandCategory"
+ id="org.eclipse.egit.ui.internal.merge.ToggleCurrentChangesCommand"
+ name="%ToggleCurrentChangesCommand.name"
+ description="%ToggleCurrentChangesCommand.description">
+ </command>
</extension>
<extension
point="org.eclipse.ui.handlers">
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
index 9e1e38e6ba..44b289eaa3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
@@ -373,6 +373,18 @@ public class UIIcons {
*/
public final static ImageDescriptor REMOVE_FROM_REPO_GROUP;
+ /**
+ * Icon for the "ignore changes from current" action in the merge editor in
+ * normal mode.
+ */
+ public final static ImageDescriptor IGNORE_LEFT_CHANGES;
+
+ /**
+ * Icon for the "ignore changes from current" action in the merge editor in
+ * mirrored mode.
+ */
+ public final static ImageDescriptor IGNORE_RIGHT_CHANGES;
+
/** base URL */
public final static URL base;
@@ -508,6 +520,8 @@ public class UIIcons {
MERGE_TOOL = map("obj16/mergetool.png"); //$NON-NLS-1$
OPEN_COMMIT = map("obj16/open-commit.png"); //$NON-NLS-1$
REMOVE_FROM_REPO_GROUP = map("obj16/clear.png"); //$NON-NLS-1$
+ IGNORE_LEFT_CHANGES = map("etool16/merge_ignore_left.png"); //$NON-NLS-1$
+ IGNORE_RIGHT_CHANGES = map("etool16/merge_ignore_right.png"); //$NON-NLS-1$
}
private static ImageDescriptor map(final String icon) {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
index fb2380e3a2..2abd724416 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
@@ -5527,6 +5527,9 @@ public class UIText extends NLS {
public static String GitMergeEditorInput_ResourceCleanupJobName;
/** */
+ public static String GitMergeEditorInput_ToggleCurrentChangesLabel;
+
+ /** */
public static String GitMergeEditorInput_WorkspaceHeader;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/CompareEditorInputViewerAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/CompareEditorInputViewerAction.java
new file mode 100644
index 0000000000..a351f11c87
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/CompareEditorInputViewerAction.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.merge;
+
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+
+/**
+ * An {@link Action} targeted at a particular {@link ContentMergeViewer} in a
+ * comparison defined by a {@link CompareEditorInput}. The action listens to
+ * changes in the {@link org.eclipse.compare.CompareConfiguration
+ * CompareConfiguration}, mainly to be able to adapt to changes regarding
+ * mirroring.
+ */
+public abstract class CompareEditorInputViewerAction extends Action
+ implements IWorkbenchAction, IPropertyChangeListener {
+
+ private final CompareEditorInput comparison;
+
+ private ContentMergeViewer viewer;
+
+ /**
+ * Creates a new {@link CompareEditorInputViewerAction}.
+ *
+ * @param name
+ * of the action
+ * @param comparison
+ * the action is for
+ */
+ protected CompareEditorInputViewerAction(String name,
+ CompareEditorInput comparison) {
+ super(name);
+ this.comparison = comparison;
+ comparison.getCompareConfiguration().addPropertyChangeListener(this);
+ }
+
+ /**
+ * Creates a new {@link CompareEditorInputViewerAction}.
+ *
+ * @param name
+ * of the action
+ * @param style
+ * of the action
+ * @param comparison
+ * the action is for
+ */
+ protected CompareEditorInputViewerAction(String name, int style,
+ CompareEditorInput comparison) {
+ super(name, style);
+ this.comparison = comparison;
+ comparison.getCompareConfiguration().addPropertyChangeListener(this);
+ }
+
+ @Override
+ public void dispose() {
+ getInput().getCompareConfiguration().removePropertyChangeListener(this);
+ }
+
+ /**
+ * Retrieves the {@link CompareEditorInput} this action was created for.
+ *
+ * @return the {@link CompareEditorInput}
+ */
+ protected CompareEditorInput getInput() {
+ return comparison;
+ }
+
+ /**
+ * Set the {@link ContentMergeViewer} this action shall target.
+ *
+ * @param viewer
+ * to set, if {@code null}, the action is disabled
+ */
+ public void setViewer(ContentMergeViewer viewer) {
+ this.viewer = viewer;
+ if (viewer == null) {
+ super.setEnabled(false);
+ }
+ }
+
+ /**
+ * Retrieves the {@link ContentMergeViewer} this action currently targets.
+ *
+ * @return the viewer, or {@code null} if none
+ */
+ protected ContentMergeViewer getViewer() {
+ return viewer;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled && viewer != null);
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
index f262886ed1..890cad078b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
@@ -21,16 +21,21 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.CompareViewerPane;
import org.eclipse.compare.IResourceProvider;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.compare.rangedifferencer.RangeDifference;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.filesystem.EFS;
@@ -66,7 +71,13 @@ import org.eclipse.egit.ui.internal.revision.FileRevisionTypedElement;
import org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement;
import org.eclipse.egit.ui.internal.revision.ResourceEditableRevision;
import org.eclipse.egit.ui.internal.synchronize.compare.LocalNonWorkspaceTypedElement;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.commands.ActionHandler;
import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jgit.api.MergeCommand.ConflictStyle;
import org.eclipse.jgit.attributes.Attribute;
import org.eclipse.jgit.attributes.Attributes;
@@ -88,19 +99,24 @@ import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.internal.ui.synchronize.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener;
import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.IHandlerActivation;
+import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.ide.IDE.SharedImages;
+import org.eclipse.ui.services.IServiceLocator;
/**
* A Git-specific {@link CompareEditorInput} for merging conflicting files.
*/
@SuppressWarnings("restriction")
public class GitMergeEditorInput extends CompareEditorInput {
+
private static final String LABELPATTERN = "{0} - {1}"; //$NON-NLS-1$
private static final Image FOLDER_IMAGE = PlatformUI.getWorkbench()
@@ -109,6 +125,8 @@ public class GitMergeEditorInput extends CompareEditorInput {
private static final Image PROJECT_IMAGE = PlatformUI.getWorkbench()
.getSharedImages().getImage(SharedImages.IMG_OBJ_PROJECT);
+ private final MergeInputMode mode;
+
private final boolean useWorkspace;
private final boolean useOurs;
@@ -117,6 +135,10 @@ public class GitMergeEditorInput extends CompareEditorInput {
private List<IFile> toDelete;
+ private Map<String, IHandlerActivation> activations = new HashMap<>();
+
+ private CompareEditorInputViewerAction toggleCurrentChanges;
+
/**
* Creates a new {@link GitMergeEditorInput}.
*
@@ -129,6 +151,7 @@ public class GitMergeEditorInput extends CompareEditorInput {
super(new CompareConfiguration());
this.useWorkspace = !MergeInputMode.STAGE_2.equals(mode);
this.useOurs = MergeInputMode.MERGED_OURS.equals(mode);
+ this.mode = mode;
this.locations = locations;
CompareConfiguration config = getCompareConfiguration();
config.setLeftEditable(true);
@@ -166,10 +189,99 @@ public class GitMergeEditorInput extends CompareEditorInput {
}
@Override
+ public Viewer findContentViewer(Viewer oldViewer, ICompareInput input,
+ Composite parent) {
+ Viewer newViewer = super.findContentViewer(oldViewer, input, parent);
+ ToolBarManager manager = CompareViewerPane.getToolBarManager(parent);
+ if (manager != null) {
+ setToggleCurrentChangesAction(manager, newViewer, input);
+ }
+ return newViewer;
+ }
+
+ @FunctionalInterface
+ private interface ActionSupplier {
+ public CompareEditorInputViewerAction get(boolean create);
+ }
+
+ private void setToggleCurrentChangesAction(ToolBarManager manager,
+ Viewer newViewer, ICompareInput input) {
+ boolean isApplicable = newViewer instanceof ContentMergeViewer
+ && input instanceof MergeDiffNode
+ && input.getAncestor() != null;
+ setAction(manager, newViewer, isApplicable,
+ ToggleCurrentChangesAction.COMMAND_ID,
+ create -> {
+ if (toggleCurrentChanges == null && create) {
+ toggleCurrentChanges = new ToggleCurrentChangesAction(
+ UIText.GitMergeEditorInput_ToggleCurrentChangesLabel,
+ this);
+ toggleCurrentChanges
+ .setId(ToggleCurrentChangesAction.COMMAND_ID);
+ }
+ return toggleCurrentChanges;
+ });
+ }
+
+ private void setAction(ToolBarManager manager, Viewer viewer,
+ boolean isApplicable, String id, ActionSupplier supplier) {
+ IContributionItem item = manager.find(id);
+ if (item != null) {
+ if (item instanceof ActionContributionItem) {
+ IAction action = ((ActionContributionItem) item).getAction();
+ if (action instanceof CompareEditorInputViewerAction) {
+ ((CompareEditorInputViewerAction) action).setViewer(
+ isApplicable ? (ContentMergeViewer) viewer : null);
+ action.setEnabled(isApplicable);
+ if (item.isVisible() != isApplicable) {
+ item.setVisible(isApplicable);
+ manager.update(true);
+ }
+ }
+ }
+ } else if (isApplicable) {
+ CompareEditorInputViewerAction action = supplier.get(true);
+ action.setViewer((ContentMergeViewer) viewer);
+ action.setEnabled(true);
+ manager.insert(0, new ActionContributionItem(action));
+ manager.update(true);
+ registerAction(action, id);
+ } else {
+ // Neither present nor applicable: disable it if it exists
+ CompareEditorInputViewerAction action = supplier.get(false);
+ if (action != null) {
+ action.setEnabled(false);
+ }
+ }
+ }
+
+ private void registerAction(IAction action, String commandId) {
+ if (activations.containsKey(commandId)) {
+ return;
+ }
+ action.setActionDefinitionId(commandId);
+ IServiceLocator locator = getContainer().getServiceLocator();
+ if (locator != null) {
+ IHandlerService handlers = locator
+ .getService(IHandlerService.class);
+ if (handlers != null) {
+ activations.put(commandId, handlers.activateHandler(commandId,
+ new ActionHandler(action)));
+ }
+ }
+ }
+
+ @Override
protected void handleDispose() {
super.handleDispose();
// We do NOT dispose the images, as these are shared.
- //
+ activations.values()
+ .forEach(a -> a.getHandlerService().deactivateHandler(a));
+ activations.clear();
+ if (toggleCurrentChanges != null) {
+ toggleCurrentChanges.dispose();
+ toggleCurrentChanges = null;
+ }
// We need to remove the temporary resources. A CompareEditorInput is
// supposed to be the very last thing that is disposed in a compare
// viewer, but this is not always true. If content merge viewers add
@@ -302,6 +414,7 @@ public class GitMergeEditorInput extends CompareEditorInput {
throw new InvocationTargetException(e);
}
+ CompareConfiguration config = getCompareConfiguration();
// try to obtain the common ancestor
RevCommit ancestorCommit = null;
boolean unknownAncestor = false;
@@ -322,6 +435,17 @@ public class GitMergeEditorInput extends CompareEditorInput {
// was taken.
unknownAncestor = true;
}
+ if (!MergeInputMode.WORKTREE.equals(mode)) {
+ // Do not suppress any changes on the left if the input is
+ // the possibly pre-merged working tree version. Conflict
+ // markers exist only on the left; they would not be shown
+ // as differences, and are then too easy to miss.
+ config.setChangeIgnored(
+ config.isMirrored() ? RangeDifference.RIGHT
+ : RangeDifference.LEFT,
+ true);
+ config.setChangeIgnored(RangeDifference.ANCESTOR, true);
+ }
break;
default:
List<RevCommit> startPoints = new ArrayList<>();
@@ -341,7 +465,6 @@ public class GitMergeEditorInput extends CompareEditorInput {
throw new InterruptedException();
}
// set the labels
- CompareConfiguration config = getCompareConfiguration();
config.setRightLabel(NLS.bind(LABELPATTERN, rightCommit
.getShortMessage(), CompareUtils.truncatedRevision(rightCommit.name())));
@@ -618,7 +741,7 @@ public class GitMergeEditorInput extends CompareEditorInput {
ancestor = new FileRevisionTypedElement(revision, encoding);
}
// create the node as child
- new DiffNode(fileParent, kind, ancestor, left, right);
+ new MergeDiffNode(fileParent, kind, ancestor, left, right);
}
return result;
} catch (URISyntaxException e) {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeDiffNode.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeDiffNode.java
new file mode 100644
index 0000000000..aa73a3d990
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeDiffNode.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.merge;
+
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.structuremergeviewer.IDiffContainer;
+import org.eclipse.egit.ui.internal.revision.NotifiableDiffNode;
+
+/**
+ * A {@link NotifiableDiffNode} specific to the Egit merge editor.
+ */
+public class MergeDiffNode extends NotifiableDiffNode {
+
+ /**
+ * Creates a new {@link MergeDiffNode} and initializes with the given
+ * values.
+ *
+ * @param parent
+ * for the new node
+ * @param kind
+ * of difference as defined in
+ * {@link org.eclipse.compare.structuremergeviewer.Differencer
+ * Differencer}
+ * @param ancestor
+ * the common ancestor input to a compare
+ * @param left
+ * the left input to a compare
+ * @param right
+ * the right input to a compare
+ * @see org.eclipse.compare.structuremergeviewer.DiffNode#DiffNode(IDiffContainer,
+ * int, ITypedElement, ITypedElement, ITypedElement)
+ */
+ public MergeDiffNode(IDiffContainer parent, int kind,
+ ITypedElement ancestor, ITypedElement left, ITypedElement right) {
+ super(parent, kind, ancestor, left, right);
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/ToggleCurrentChangesAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/ToggleCurrentChangesAction.java
new file mode 100644
index 0000000000..13efe83702
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/ToggleCurrentChangesAction.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.merge;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.compare.rangedifferencer.RangeDifference;
+import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * An {@link Action} to toggle showing changes between the ancestor and the
+ * 'current' ('ours') side in a three-way comparison.
+ * <p>
+ * Compare viewers with swapped sides are a nuisance. One would expect this to
+ * be transparent and all "left" things simply mean "right" and vice versa.
+ * Alas, this is not the case. The ContentMergeViewer swaps the inputs, but that
+ * means that RangeDifference.LEFT still means "left" and now refers to
+ * 'theirs'. Ugh.
+ * </p>
+ */
+public class ToggleCurrentChangesAction extends CompareEditorInputViewerAction {
+
+ /**
+ * The command ID for this action.
+ */
+ public static final String COMMAND_ID = "org.eclipse.egit.ui.internal.merge.ToggleCurrentChangesCommand"; //$NON-NLS-1$
+
+ /**
+ * Creates a new {@link ToggleCurrentChangesAction}.
+ *
+ * @param title
+ * for the action
+ * @param comparison
+ * to modify
+ */
+ public ToggleCurrentChangesAction(String title,
+ CompareEditorInput comparison) {
+ super(title, IAction.AS_CHECK_BOX, comparison);
+ CompareConfiguration config = comparison.getCompareConfiguration();
+ setChecked(config.isChangeIgnored(currentSide(config)));
+ if (config.isMirrored()) {
+ setImageDescriptor(UIIcons.IGNORE_RIGHT_CHANGES);
+ } else {
+ setImageDescriptor(UIIcons.IGNORE_LEFT_CHANGES);
+ }
+ addEventListeners(config);
+ }
+
+ @SuppressWarnings("restriction")
+ private void addEventListeners(CompareConfiguration config) {
+ config.addPropertyChangeListener(event -> {
+ if (org.eclipse.compare.internal.ICompareUIConstants.PROP_IGNORE_ANCESTOR
+ .equals(event.getProperty())) {
+ boolean threeWay = isThreeWay(config);
+ if (threeWay) {
+ super.setEnabled(true);
+ if (isEnabled()) {
+ run();
+ }
+ } else {
+ super.setEnabled(false);
+ forceOff();
+ }
+ }
+ });
+ }
+
+ private boolean isThreeWay(CompareConfiguration config) {
+ @SuppressWarnings("restriction")
+ Object property = config.getProperty(
+ org.eclipse.compare.internal.ICompareUIConstants.PROP_IGNORE_ANCESTOR);
+ if (property instanceof Boolean) {
+ return !((Boolean) property).booleanValue();
+ } else if (property == null) {
+ return true;
+ }
+ return !Boolean.parseBoolean(property.toString());
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(
+ enabled && isThreeWay(getInput().getCompareConfiguration()));
+ }
+
+ @Override
+ public void run() {
+ ContentMergeViewer viewer = getViewer();
+ if (viewer == null) {
+ return;
+ }
+ Object input = viewer.getInput();
+ if (input instanceof MergeDiffNode) {
+ boolean ignoreLeft = isChecked();
+ CompareConfiguration config = getInput().getCompareConfiguration();
+ int side = currentSide(config);
+ int otherSide = side == RangeDifference.LEFT ? RangeDifference.RIGHT
+ : RangeDifference.LEFT;
+ boolean anyDifference = ignoreLeft != config.isChangeIgnored(side);
+ anyDifference |= ignoreLeft != config
+ .isChangeIgnored(RangeDifference.ANCESTOR);
+ anyDifference |= config.isChangeIgnored(otherSide);
+ if (anyDifference) {
+ config.setChangeIgnored(side, ignoreLeft);
+ config.setChangeIgnored(RangeDifference.ANCESTOR, ignoreLeft);
+ config.setChangeIgnored(otherSide, false);
+ ((MergeDiffNode) input).fireChange();
+ }
+ }
+ }
+
+ private void forceOff() {
+ ContentMergeViewer viewer = getViewer();
+ if (viewer == null) {
+ return;
+ }
+ Object input = viewer.getInput();
+ if (input instanceof MergeDiffNode) {
+ CompareConfiguration config = getInput().getCompareConfiguration();
+ boolean anyIgnored = config.isChangeIgnored(RangeDifference.LEFT);
+ anyIgnored |= config.isChangeIgnored(RangeDifference.ANCESTOR);
+ anyIgnored |= config.isChangeIgnored(RangeDifference.RIGHT);
+ if (anyIgnored) {
+ config.setChangeIgnored(RangeDifference.LEFT, false);
+ config.setChangeIgnored(RangeDifference.ANCESTOR, false);
+ config.setChangeIgnored(RangeDifference.RIGHT, false);
+ ((MergeDiffNode) input).fireChange();
+ }
+ }
+ }
+
+ private int currentSide(CompareConfiguration config) {
+ if (config.isMirrored()) {
+ return RangeDifference.RIGHT;
+ }
+ return RangeDifference.LEFT;
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ if (CompareConfiguration.MIRRORED.equals(event.getProperty())) {
+ if (getInput().getCompareConfiguration().isMirrored()) {
+ setImageDescriptor(UIIcons.IGNORE_RIGHT_CHANGES);
+ } else {
+ setImageDescriptor(UIIcons.IGNORE_LEFT_CHANGES);
+ }
+ if (isEnabled()) {
+ run();
+ }
+ }
+ }
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/NotifiableDiffNode.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/NotifiableDiffNode.java
index 1b9b35a024..fdd3bd3eb5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/NotifiableDiffNode.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/NotifiableDiffNode.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 IBM Corporation and others.
+ * Copyright (c) 2011, 2021 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -16,16 +16,37 @@ import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
-class NotifiableDiffNode extends DiffNode {
+/**
+ * A {@link DiffNode} with a public {@link #fireChange()} method.
+ */
+public class NotifiableDiffNode extends DiffNode {
- NotifiableDiffNode(IDiffContainer parent, int kind, ITypedElement ancestor,
- ITypedElement left, ITypedElement right) {
+ /**
+ * Creates a new {@link NotifiableDiffNode} and initializes with the given
+ * values.
+ *
+ * @param parent
+ * for the new node
+ * @param kind
+ * of difference as defined in
+ * {@link org.eclipse.compare.structuremergeviewer.Differencer
+ * Differencer}
+ * @param ancestor
+ * the common ancestor input to a compare
+ * @param left
+ * the left input to a compare
+ * @param right
+ * the right input to a compare
+ * @see DiffNode#DiffNode(IDiffContainer, int, ITypedElement, ITypedElement,
+ * ITypedElement)
+ */
+ public NotifiableDiffNode(IDiffContainer parent, int kind,
+ ITypedElement ancestor, ITypedElement left, ITypedElement right) {
super(parent, kind, ancestor, left, right);
}
@Override
- protected void fireChange() {
+ public void fireChange() {
super.fireChange();
}
-
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
index b82be3dd16..7eb0bf5192 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
@@ -1966,6 +1966,7 @@ GitMergeEditorInput_CheckingResourcesTaskName=Checking resources
GitMergeEditorInput_ErrorUpdatingIndex=Merge editor could not update the git index for conflict path ''{0}''
GitMergeEditorInput_MergeEditorTitle=Repository ''{0}'': Merging ''{1}'' into ''{2}''
GitMergeEditorInput_ResourceCleanupJobName=Cleaning Hidden Resources
+GitMergeEditorInput_ToggleCurrentChangesLabel=&Hide Changes Between Current and Ancestor
GitMergeEditorInput_WorkspaceHeader=Working Tree Version
GitMergeEditorInput_WorkspaceOursHeader=Pre-merged Local Version ('Ours')

Back to the top