Add plugins
Signed-off-by: Axel Richard <axel.richard@obeo.fr>
diff --git a/org.eclipse.emf.compare.git.pgm.parent/.project b/org.eclipse.emf.compare.git.pgm.parent/.project
new file mode 100644
index 0000000..0a1683e
--- /dev/null
+++ b/org.eclipse.emf.compare.git.pgm.parent/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.compare.git.pgm.parent</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.emf.compare.git.pgm.parent/about.html b/org.eclipse.emf.compare.git.pgm.parent/about.html
new file mode 100644
index 0000000..5507b29
--- /dev/null
+++ b/org.eclipse.emf.compare.git.pgm.parent/about.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Foundation Software User Agreement</title>
+</head>
+
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>April 14, 2010</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+ repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+ Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or
+ other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to
+ install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a
+ href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+ ("Specification").</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+ applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+ in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+ Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+ <li>A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology
+ on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based
+ product.</li>
+ <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+ accessed and copied to the Target Machine.</li>
+ <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+ Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target
+ Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+ the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+ indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/org.eclipse.emf.compare.git.pgm.parent/pom.xml b/org.eclipse.emf.compare.git.pgm.parent/pom.xml
new file mode 100644
index 0000000..0194f29
--- /dev/null
+++ b/org.eclipse.emf.compare.git.pgm.parent/pom.xml
@@ -0,0 +1,91 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <parent-version>1.0.0-SNAPSHOT</parent-version>
+ <tycho-version>0.21.0</tycho-version>
+ <tycho-extras-version>0.21.0</tycho-extras-version>
+ <maven-surefire-version>2.17</maven-surefire-version>
+ </properties>
+ <modules>
+ <module>../plugins/org.eclipse.emf.compare.git.pgm</module>
+ <module>../plugins/org.eclipse.emf.compare.git.pgm.tests</module>
+ <module>../packaging/org.eclipse.emf.compare.git.pgm.product</module>
+ <module>../packaging/org.eclipse.emf.compare.git.pgm.feature</module>
+ <module>../packaging/org.eclipse.emf.compare.git.pgm.update</module>
+ </modules>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>tycho-snapshots</id>
+ <url>https://oss.sonatype.org/content/groups/public/</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <repositories>
+ <repository>
+ <id>eclipse-luna</id>
+ <url>http://download.eclipse.org/releases/luna</url>
+ <layout>p2</layout>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-maven-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <target>
+ <artifact>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.parent</artifactId>
+ <version>${parent-version}</version>
+ <classifier>targetPlatforms/org.eclipse.emf.compare.git.pgm</classifier>
+ </artifact>
+ </target>
+ <environments>
+ <environment>
+ <os>win32</os>
+ <ws>win32</ws>
+ <arch>x86</arch>
+ </environment>
+ <environment>
+ <os>win32</os>
+ <ws>win32</ws>
+ <arch>x86_64</arch>
+ </environment>
+ <environment>
+ <os>linux</os>
+ <ws>gtk</ws>
+ <arch>x86</arch>
+ </environment>
+ <environment>
+ <os>linux</os>
+ <ws>gtk</ws>
+ <arch>x86_64</arch>
+ </environment>
+ <environment>
+ <os>macosx</os>
+ <ws>cocoa</ws>
+ <arch>x86_64</arch>
+ </environment>
+ </environments>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.emf.compare.git.pgm.parent/targetPlatforms/org.eclipse.emf.compare.git.pgm.target b/org.eclipse.emf.compare.git.pgm.parent/targetPlatforms/org.eclipse.emf.compare.git.pgm.target
new file mode 100644
index 0000000..7fe1c5b
--- /dev/null
+++ b/org.eclipse.emf.compare.git.pgm.parent/targetPlatforms/org.eclipse.emf.compare.git.pgm.target
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
+<target name="EMF Compare Git PGM target platform" sequenceNumber="1411133145">
+ <locations>
+ <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
+ <unit id="org.eclipse.platform.sdk" version="0.0.0"/>
+ <unit id="org.eclipse.emf.sdk.feature.group" version="0.0.0"/>
+ <unit id="org.eclipse.emf.transaction.sdk.feature.group" version="0.0.0"/>
+ <unit id="org.eclipse.uml2.feature.group" version="0.0.0"/>
+ <unit id="org.eclipse.gmf.runtime.notation.sdk.feature.group" version="0.0.0"/>
+ <unit id="org.eclipse.papyrus.sdk.feature.feature.group" version="0.0.0"/>
+ <repository location="http://download.eclipse.org/releases/luna"/>
+ </location>
+ <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
+ <unit id="org.eclipse.oomph.util" version="0.0.0"/>
+ <unit id="org.eclipse.oomph.base.edit" version="0.0.0"/>
+ <unit id="org.eclipse.oomph.setup" version="0.0.0"/>
+ <unit id="org.eclipse.oomph.setup.core" version="0.0.0"/>
+ <unit id="org.eclipse.oomph.setup.projects" version="0.0.0"/>
+ <unit id="org.eclipse.oomph.setup.p2" version="0.0.0"/>
+ <repository location="https://hudson.eclipse.org/oomph/job/integration/lastSuccessfulBuild/artifact/updates/"/>
+ </location>
+ <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
+ <unit id="org.eclipse.emf.compare.ide.ui.source.feature.group" version="0.0.0"/>
+ <unit id="org.eclipse.emf.compare.uml2.feature.group" version="0.0.0"/>
+ <unit id="org.eclipse.emf.compare.diagram.gmf.feature.group" version="0.0.0"/>
+ <unit id="org.eclipse.emf.compare.diagram.papyrus.feature.group" version="0.0.0"/>
+ <repository location="http://download.eclipse.org/modeling/emf/compare/updates/nightly/latest/"/>
+ </location>
+ <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
+ <unit id="org.eclipse.egit.feature.group" version="0.0.0"/>
+ <repository location="http://ericssonegit.ci.obeo.fr:8180/jenkins/job/egit-logical/lastSuccessfulBuild/artifact/org.eclipse.egit.repository/target/repository/"/>
+ </location>
+ <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
+ <unit id="org.eclipse.license.feature.group" version="1.0.1.v20140414-1359"/>
+ <repository location="http://download.eclipse.org/cbi/updates/license"/>
+ </location>
+ <location includeMode="planner" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
+ <unit id="com.google.guava" version="11.0.2.v201303041551"/>
+ <unit id="org.junit" version="4.11.0.v201303080030"/>
+ <unit id="javaewah" version="0.7.9.v201401101600"/>
+ <unit id="org.apache.commons.compress" version="1.6.0.v201310281400"/>
+ <unit id="org.kohsuke.args4j" version="2.0.21.v201301150030"/>
+ <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/"/>
+ </location>
+ </locations>
+</target>
diff --git a/org.eclipse.emf.compare.git.pgm.parent/targetPlatforms/org.eclipse.emf.compare.git.pgm.tpd b/org.eclipse.emf.compare.git.pgm.parent/targetPlatforms/org.eclipse.emf.compare.git.pgm.tpd
new file mode 100644
index 0000000..17d2775
--- /dev/null
+++ b/org.eclipse.emf.compare.git.pgm.parent/targetPlatforms/org.eclipse.emf.compare.git.pgm.tpd
@@ -0,0 +1,47 @@
+target "EMF Compare Git PGM target platform"
+
+with source requirements
+
+location "http://download.eclipse.org/releases/luna" {
+ org.eclipse.platform.sdk lazy
+ org.eclipse.emf.sdk.feature.group lazy
+ org.eclipse.emf.transaction.sdk.feature.group lazy
+ org.eclipse.uml2.feature.group lazy
+ org.eclipse.gmf.runtime.notation.sdk.feature.group lazy
+ org.eclipse.papyrus.sdk.feature.feature.group lazy
+ }
+
+location "https://hudson.eclipse.org/oomph/job/integration/lastSuccessfulBuild/artifact/updates/" {
+ org.eclipse.oomph.util lazy
+ org.eclipse.oomph.base.edit lazy
+ org.eclipse.oomph.setup lazy
+ org.eclipse.oomph.setup.core lazy
+ org.eclipse.oomph.setup.projects lazy
+ org.eclipse.oomph.setup.p2 lazy
+
+}
+location "http://download.eclipse.org/modeling/emf/compare/updates/nightly/latest/" {
+ org.eclipse.emf.compare.ide.ui.source.feature.group lazy
+ org.eclipse.emf.compare.uml2.feature.group lazy
+ org.eclipse.emf.compare.diagram.gmf.feature.group lazy
+ org.eclipse.emf.compare.diagram.papyrus.feature.group lazy
+}
+
+location "http://ericssonegit.ci.obeo.fr:8180/jenkins/job/egit-logical/lastSuccessfulBuild/artifact/org.eclipse.egit.repository/target/repository/" {
+ org.eclipse.egit.feature.group lazy
+}
+
+location "http://download.eclipse.org/cbi/updates/license" {
+ org.eclipse.license.feature.group [1.0.1,1.1.0)
+}
+
+location "http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/" {
+ com.google.guava [11.0.2,11.0.3)
+ org.junit [4,5)
+
+ /* Egit/Jgit */
+ javaewah
+ org.apache.commons.compress
+ org.kohsuke.args4j
+ /* Egit/Jgit */
+}
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.feature/.project b/packaging/org.eclipse.emf.compare.git.pgm.feature/.project
new file mode 100644
index 0000000..b11ff7e
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.compare.git.pgm.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.feature/build.properties b/packaging/org.eclipse.emf.compare.git.pgm.feature/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.feature/feature.xml b/packaging/org.eclipse.emf.compare.git.pgm.feature/feature.xml
new file mode 100644
index 0000000..4106906
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.feature/feature.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.emf.compare.git.pgm.feature"
+ label="EMF Compare Git PGM Feature"
+ version="1.0.0.qualifier">
+
+ <description url="http://www.example.com/description">
+ [Enter Feature Description here.]
+ </description>
+
+ <copyright url="http://www.example.com/copyright">
+ [Enter Copyright Description here.]
+ </copyright>
+
+ <license url="http://www.example.com/license">
+ [Enter License Description here.]
+ </license>
+
+ <plugin
+ id="org.eclipse.emf.compare.git.pgm"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.feature/pom.xml b/packaging/org.eclipse.emf.compare.git.pgm.feature/pom.xml
new file mode 100644
index 0000000..022daf0
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.feature/pom.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../org.eclipse.emf.compare.git.pgm.parent/</relativePath>
+ </parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.feature</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-feature</packaging>
+</project>
\ No newline at end of file
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.product/.project b/packaging/org.eclipse.emf.compare.git.pgm.product/.project
new file mode 100644
index 0000000..e010072
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.product/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.compare.git.pgm.product</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.product/about.html b/packaging/org.eclipse.emf.compare.git.pgm.product/about.html
new file mode 100644
index 0000000..5507b29
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.product/about.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Foundation Software User Agreement</title>
+</head>
+
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>April 14, 2010</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+ repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+ Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or
+ other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to
+ install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a
+ href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+ ("Specification").</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+ applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+ in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+ Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+ <li>A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology
+ on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based
+ product.</li>
+ <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+ accessed and copied to the Target Machine.</li>
+ <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+ Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target
+ Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+ the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+ indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.product/logicalmerge.product b/packaging/org.eclipse.emf.compare.git.pgm.product/logicalmerge.product
new file mode 100644
index 0000000..f4d9024
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.product/logicalmerge.product
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="Logical Merge" uid="org.eclipse.emf.compare.git.pgm.product" id="org.eclipse.emf.compare.git.pgm.product" application="org.eclipse.emf.compare.git.pgm.application" useFeatures="false" includeLaunchers="true">
+
+ <configIni use="default">
+ </configIni>
+
+ <launcherArgs>
+ <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts
+ </vmArgsMac>
+ </launcherArgs>
+
+ <launcher name="emfcompare-git-pgm">
+ <solaris/>
+ <win useIco="false">
+ <bmp/>
+ </win>
+ </launcher>
+
+ <vm>
+ </vm>
+
+ <plugins>
+ <plugin id="com.google.guava"/>
+ <plugin id="com.ibm.icu"/>
+ <plugin id="com.jcraft.jsch"/>
+ <plugin id="javaewah"/>
+ <plugin id="javax.annotation"/>
+ <plugin id="javax.inject"/>
+ <plugin id="javax.servlet"/>
+ <plugin id="javax.xml"/>
+ <plugin id="org.apache.batik.css"/>
+ <plugin id="org.apache.batik.util"/>
+ <plugin id="org.apache.batik.util.gui"/>
+ <plugin id="org.apache.commons.codec"/>
+ <plugin id="org.apache.commons.logging"/>
+ <plugin id="org.apache.httpcomponents.httpclient"/>
+ <plugin id="org.apache.httpcomponents.httpcore"/>
+ <plugin id="org.eclipse.ant.core"/>
+ <plugin id="org.eclipse.compare"/>
+ <plugin id="org.eclipse.compare.core"/>
+ <plugin id="org.eclipse.core.commands"/>
+ <plugin id="org.eclipse.core.contenttype"/>
+ <plugin id="org.eclipse.core.databinding"/>
+ <plugin id="org.eclipse.core.databinding.beans"/>
+ <plugin id="org.eclipse.core.databinding.observable"/>
+ <plugin id="org.eclipse.core.databinding.property"/>
+ <plugin id="org.eclipse.core.expressions"/>
+ <plugin id="org.eclipse.core.filebuffers"/>
+ <plugin id="org.eclipse.core.filesystem"/>
+ <plugin id="org.eclipse.core.filesystem.java7" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.core.jobs"/>
+ <plugin id="org.eclipse.core.net"/>
+ <plugin id="org.eclipse.core.net.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.core.resources"/>
+ <plugin id="org.eclipse.core.runtime"/>
+ <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
+ <plugin id="org.eclipse.core.variables"/>
+ <plugin id="org.eclipse.e4.core.commands"/>
+ <plugin id="org.eclipse.e4.core.contexts"/>
+ <plugin id="org.eclipse.e4.core.di"/>
+ <plugin id="org.eclipse.e4.core.di.extensions"/>
+ <plugin id="org.eclipse.e4.core.services"/>
+ <plugin id="org.eclipse.e4.ui.bindings"/>
+ <plugin id="org.eclipse.e4.ui.css.core"/>
+ <plugin id="org.eclipse.e4.ui.css.swt"/>
+ <plugin id="org.eclipse.e4.ui.css.swt.theme"/>
+ <plugin id="org.eclipse.e4.ui.di"/>
+ <plugin id="org.eclipse.e4.ui.model.workbench"/>
+ <plugin id="org.eclipse.e4.ui.services"/>
+ <plugin id="org.eclipse.e4.ui.widgets"/>
+ <plugin id="org.eclipse.e4.ui.workbench"/>
+ <plugin id="org.eclipse.e4.ui.workbench.addons.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench.renderers.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench3"/>
+ <plugin id="org.eclipse.ecf"/>
+ <plugin id="org.eclipse.ecf.filetransfer"/>
+ <plugin id="org.eclipse.ecf.identity"/>
+ <plugin id="org.eclipse.ecf.provider.filetransfer"/>
+ <plugin id="org.eclipse.ecf.provider.filetransfer.ssl" fragment="true"/>
+ <plugin id="org.eclipse.ecf.ssl" fragment="true"/>
+ <plugin id="org.eclipse.egit.core"/>
+ <plugin id="org.eclipse.emf.common"/>
+ <plugin id="org.eclipse.emf.common.ui"/>
+ <plugin id="org.eclipse.emf.compare"/>
+ <plugin id="org.eclipse.emf.compare.edit"/>
+ <plugin id="org.eclipse.emf.compare.git.pgm"/>
+ <plugin id="org.eclipse.emf.compare.ide"/>
+ <plugin id="org.eclipse.emf.compare.ide.ui"/>
+ <plugin id="org.eclipse.emf.compare.rcp"/>
+ <plugin id="org.eclipse.emf.compare.rcp.ui"/>
+ <plugin id="org.eclipse.emf.ecore"/>
+ <plugin id="org.eclipse.emf.ecore.change"/>
+ <plugin id="org.eclipse.emf.ecore.edit"/>
+ <plugin id="org.eclipse.emf.ecore.xmi"/>
+ <plugin id="org.eclipse.emf.edit"/>
+ <plugin id="org.eclipse.emf.edit.ui"/>
+ <plugin id="org.eclipse.emf.transaction"/>
+ <plugin id="org.eclipse.emf.validation"/>
+ <plugin id="org.eclipse.equinox.app"/>
+ <plugin id="org.eclipse.equinox.bidi"/>
+ <plugin id="org.eclipse.equinox.common"/>
+ <plugin id="org.eclipse.equinox.concurrent"/>
+ <plugin id="org.eclipse.equinox.ds"/>
+ <plugin id="org.eclipse.equinox.event"/>
+ <plugin id="org.eclipse.equinox.frameworkadmin"/>
+ <plugin id="org.eclipse.equinox.frameworkadmin.equinox"/>
+ <plugin id="org.eclipse.equinox.p2.artifact.repository"/>
+ <plugin id="org.eclipse.equinox.p2.console"/>
+ <plugin id="org.eclipse.equinox.p2.core"/>
+ <plugin id="org.eclipse.equinox.p2.director"/>
+ <plugin id="org.eclipse.equinox.p2.director.app"/>
+ <plugin id="org.eclipse.equinox.p2.engine"/>
+ <plugin id="org.eclipse.equinox.p2.garbagecollector"/>
+ <plugin id="org.eclipse.equinox.p2.jarprocessor"/>
+ <plugin id="org.eclipse.equinox.p2.metadata"/>
+ <plugin id="org.eclipse.equinox.p2.metadata.repository"/>
+ <plugin id="org.eclipse.equinox.p2.operations"/>
+ <plugin id="org.eclipse.equinox.p2.publisher"/>
+ <plugin id="org.eclipse.equinox.p2.publisher.eclipse"/>
+ <plugin id="org.eclipse.equinox.p2.repository"/>
+ <plugin id="org.eclipse.equinox.p2.repository.tools"/>
+ <plugin id="org.eclipse.equinox.p2.touchpoint.eclipse"/>
+ <plugin id="org.eclipse.equinox.p2.touchpoint.natives"/>
+ <plugin id="org.eclipse.equinox.p2.transport.ecf"/>
+ <plugin id="org.eclipse.equinox.p2.updatesite"/>
+ <plugin id="org.eclipse.equinox.preferences"/>
+ <plugin id="org.eclipse.equinox.registry"/>
+ <plugin id="org.eclipse.equinox.security"/>
+ <plugin id="org.eclipse.equinox.simpleconfigurator"/>
+ <plugin id="org.eclipse.equinox.simpleconfigurator.manipulator"/>
+ <plugin id="org.eclipse.equinox.util"/>
+ <plugin id="org.eclipse.help"/>
+ <plugin id="org.eclipse.jface"/>
+ <plugin id="org.eclipse.jface.databinding"/>
+ <plugin id="org.eclipse.jface.text"/>
+ <plugin id="org.eclipse.jgit"/>
+ <plugin id="org.eclipse.oomph.base"/>
+ <plugin id="org.eclipse.oomph.base.edit"/>
+ <plugin id="org.eclipse.oomph.p2"/>
+ <plugin id="org.eclipse.oomph.p2.core"/>
+ <plugin id="org.eclipse.oomph.predicates"/>
+ <plugin id="org.eclipse.oomph.preferences"/>
+ <plugin id="org.eclipse.oomph.resources"/>
+ <plugin id="org.eclipse.oomph.setup"/>
+ <plugin id="org.eclipse.oomph.setup.core"/>
+ <plugin id="org.eclipse.oomph.setup.p2"/>
+ <plugin id="org.eclipse.oomph.setup.projects"/>
+ <plugin id="org.eclipse.oomph.util"/>
+ <plugin id="org.eclipse.osgi"/>
+ <plugin id="org.eclipse.osgi.compatibility.state" fragment="true"/>
+ <plugin id="org.eclipse.osgi.services"/>
+ <plugin id="org.eclipse.swt"/>
+ <plugin id="org.eclipse.swt.gtk.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.team.core"/>
+ <plugin id="org.eclipse.team.ui"/>
+ <plugin id="org.eclipse.text"/>
+ <plugin id="org.eclipse.ui"/>
+ <plugin id="org.eclipse.ui.editors"/>
+ <plugin id="org.eclipse.ui.forms"/>
+ <plugin id="org.eclipse.ui.ide"/>
+ <plugin id="org.eclipse.ui.navigator"/>
+ <plugin id="org.eclipse.ui.views"/>
+ <plugin id="org.eclipse.ui.workbench"/>
+ <plugin id="org.eclipse.ui.workbench.texteditor"/>
+ <plugin id="org.hamcrest.core"/>
+ <plugin id="org.junit"/>
+ <plugin id="org.kohsuke.args4j"/>
+ <plugin id="org.sat4j.core"/>
+ <plugin id="org.sat4j.pb"/>
+ <plugin id="org.w3c.css.sac"/>
+ <plugin id="org.w3c.dom.events"/>
+ <plugin id="org.w3c.dom.smil"/>
+ <plugin id="org.w3c.dom.svg"/>
+ </plugins>
+
+ <configurations>
+ <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="4" />
+ <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
+ <plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="1" />
+ <plugin id="org.eclipse.equinox.simpleconfigurator" autoStart="true" startLevel="1" />
+ <plugin id="org.eclipse.update.configurator" autoStart="true" startLevel="3" />
+ </configurations>
+
+</product>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.product/pom.xml b/packaging/org.eclipse.emf.compare.git.pgm.product/pom.xml
new file mode 100644
index 0000000..56ce400
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.product/pom.xml
@@ -0,0 +1,61 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../org.eclipse.emf.compare.git.pgm.parent/</relativePath>
+ </parent>
+
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.product</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-repository</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-repository-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <includeAllDependencies>true</includeAllDependencies>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-director-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <products>
+ <product>
+ <id>org.eclipse.emf.compare.git.pgm.product</id>
+ <rootFolder>emfcompare-git-pgm</rootFolder>
+ <archiveFileName>emfcompare-git-pgm-${unqualifiedVersion}</archiveFileName>
+ </product>
+ </products>
+ <formats>
+ <linux>tar.gz</linux>
+ <macosx>tar.gz</macosx>
+ </formats>
+ </configuration>
+ <executions>
+ <execution>
+ <id>materialize-products</id>
+ <goals>
+ <goal>materialize-products</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>archive-products</id>
+ <goals>
+ <goal>archive-products</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/.project b/packaging/org.eclipse.emf.compare.git.pgm.scripts/.project
new file mode 100644
index 0000000..52385dc
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.compare.git.pgm.scripts</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.dltk.core.scriptbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>net.sourceforge.shelled.core.nature</nature>
+ </natures>
+</projectDescription>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/README.txt b/packaging/org.eclipse.emf.compare.git.pgm.scripts/README.txt
new file mode 100644
index 0000000..26a3b19
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/README.txt
@@ -0,0 +1 @@
+In order to use any script you need to check the variable EMF_COMPARE_GIT_PGM_PATH is correctly set (see tests/logicalcommands_tests.sh for an example).
\ No newline at end of file
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/about.html b/packaging/org.eclipse.emf.compare.git.pgm.scripts/about.html
new file mode 100644
index 0000000..5507b29
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/about.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Foundation Software User Agreement</title>
+</head>
+
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>April 14, 2010</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+ repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+ Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or
+ other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to
+ install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a
+ href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+ ("Specification").</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+ applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+ in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+ Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+ <li>A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology
+ on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based
+ product.</li>
+ <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+ accessed and copied to the Target Machine.</li>
+ <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+ Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target
+ Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+ the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+ indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/commandconfiguration.sh b/packaging/org.eclipse.emf.compare.git.pgm.scripts/commandconfiguration.sh
new file mode 100644
index 0000000..eaa9399
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/commandconfiguration.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# ====================================================================
+# Copyright (c) 2014 Obeo
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+# ====================================================================
+
+# Runs the emfcompare-git.pgm application fowarding the arguments.
+emfcompare-git-pgm (){
+ #java -Dequinox.use.ds=true -jar $EMF_COMPARE_GIT_PGM_PATH/plugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar -consoleLog -nosplash -application emf.compare.git.launcherApp "$@"
+ $EMF_COMPARE_GIT_PGM_PATH/emfcompare-git-pgm -data @user.home/.emfcompare_git_pgm/workspace -consoleLog -nosplash --launcher.suppressErrors -application emf.compare.git.launcherApp "$@"
+}
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicaldiff b/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicaldiff
new file mode 100644
index 0000000..e7387ca
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicaldiff
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# ====================================================================
+# Copyright (c) 2014 Obeo
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+# ====================================================================
+
+source commandconfiguration.sh
+
+#Run this application as a logicalmerge command.
+emfcompare-git-pgm logicaldiff "$@"
\ No newline at end of file
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicalmerge b/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicalmerge
new file mode 100644
index 0000000..6a344ff
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicalmerge
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# ====================================================================
+# Copyright (c) 2014 Obeo
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+# ====================================================================
+
+source commandconfiguration.sh
+
+#Run this application as a logicalmerge command.
+emfcompare-git-pgm logicalmerge "$@"
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicalmergetool b/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicalmergetool
new file mode 100644
index 0000000..da37075
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/git-logicalmergetool
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# ====================================================================
+# Copyright (c) 2014 Obeo
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+# ====================================================================
+
+source commandconfiguration.sh
+
+#Run this application as a logicalmerge command.
+emfcompare-git-pgm logicalmergetool "$@"
\ No newline at end of file
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/Utils.sh b/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/Utils.sh
new file mode 100644
index 0000000..0275663
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/Utils.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# ====================================================================
+# Copyright (c) 2014 Obeo
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+# ====================================================================
+
+# Util class for testing logical command integration
+
+#Configures the util class.
+# $1 the path to the workspace
+# $2 name of the repository
+config(){
+ echo "# Configuration:"
+ workspace=$1
+ echo "# Current workspace" $workspace
+ repositoryName=$2
+ echo "# Repository name" $repositoryName
+ repoPath=$workspace/$repositoryName
+ echo "# Repository path" $repoPath
+ echo ""
+}
+
+# Runs an command and assert the outputs
+# $1 Command
+# $2 Expected return code
+# $3 Expected out
+# $4 Test name
+assertCommandOutput (){
+ result=$($1)
+ returnCode=$?
+
+ #Checks return code
+ if [ "$returnCode" -ne "$2" ]; then
+ echo "*** ERROR Unexpected return code while running \"$1\" ****"
+ echo "Test name: $4"
+ echo "Expected $2 but was $returnCode"
+ echo ""
+ #exit -1
+ fi
+ if [ "$result" != "$3" ]; then
+ echo "*** ERROR Unexpected out while running \"$1\" ****"
+ echo "Test name: $4"
+ echo "Expected:"
+ echo "$3"
+ echo "Actual:"
+ echo "$result"
+ echo ""
+ #exit -1
+ fi
+}
+
+# Creates a new repo and sets the context for next command at the root of this repo.
+createRepo(){
+ cd $workspace
+ git init $repositoryName
+ cd $repositoryName
+}
+# Creates a new file
+# $1 = File name
+# $2 = File content
+createFileInRepo(){
+ echo $2 > $workspace/$repositoryName/$1
+}
+# Sets the current context for the next command to the root of the git repository.
+goToRepoRoot () {
+ cd $repoPath
+}
+# Sets the current context for the next command to the root of the workspace.
+goToWorkspace (){
+ cd $workspace
+}
+# Adds all unstaged file to the stage area.
+addAllToStageArea () {
+ goToRepoRoot
+ git add .
+}
+
+# Commits what is the staged area
+# $1 Message
+# echo the id of the new commit
+commitAndGetId () {
+ goToRepoRoot
+ git commit -m "$1" > /dev/null 2>&1
+ local myResult="$(git log -n 1 2>&1 | sed 's/commit\s//' | head -c7)"
+ echo $myResult
+}
+
+
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/logicalcommands_test.sh b/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/logicalcommands_test.sh
new file mode 100644
index 0000000..713c43c
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/logicalcommands_test.sh
@@ -0,0 +1,170 @@
+#!/bin/bash
+# ====================================================================
+# Copyright (c) 2014 Obeo
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+# ====================================================================
+
+# This script aims to test all 3 logical commands:
+# logicalmerge
+# logicaldiff
+# logicalmertool
+# This script has to be updated regarding the developpment state.
+
+set -o nounset
+set -o errexit
+#set -o errtrace
+#set -o functrace
+#set -o xtrace
+
+source Utils.sh
+
+#Location of the current script
+scriptLocation="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+# If the test in run on a linux gtk x86_64
+# TODO improve this
+export EMF_COMPARE_GIT_PGM_PATH="$scriptLocation/../../org.eclipse.emf.compare.git.pgm.product/target/products/org.eclipse.emf.compare.git.pgm.product/linux/gtk/x86_64/emfcompare-git-pgm"
+
+#Unique Id used to build a workspace
+UUID=$(cat /proc/sys/kernel/random/uuid)
+#Creates workspace
+currentWorkspace="/tmp/workspace$UUID"
+mkdir $currentWorkspace
+
+echo "***************************************************************"
+echo "Starting integration test"
+
+# Adds the location of the folder holding git scripts to the path. This way the command "git SCRIPT_NAME ARGS" will work.
+PATH=$scriptLocation/..:$PATH
+
+# Configures the workspace and the repository location
+config $currentWorkspace 'logicalMergeRepo'
+
+
+# Creates a fake Oomph configuration file
+goToWorkspace
+echo 'Some configuration...' > setup.setup
+
+# Creates a new test repo
+createRepo
+
+# Create a new file in the repo folder
+createFileInRepo "newFile.txt" "some content"
+
+# Adds all unstage files to the staged area
+addAllToStageArea
+
+# Commits
+commitId=$(commitAndGetId 'First commit')
+
+########################################## Starts testing the logicalmerge command ##########################################################
+
+# Tests the logicalmerge command without any argument
+expectedOut="fatal: Argument \"<setup>\" is required in:
+
+logicalmerge <setup> <commit> [--help (-h)] [-m message]
+
+ <setup> : Path to the setup file. The setup file is a Oomph model
+ <commit> : Commit ID or branch name to merge
+ --help (-h) : Dispays help for this command
+ -m message : Set the commit message to be used for the merge commit (in case
+ one is created)."
+
+assertCommandOutput "git logicalmerge" 128 "$expectedOut" "The the logical merge command without any argument" || true
+
+assertCommandOutput "git logicalmerge ../incorectLocation.setup master" 128 "fatal: ../incorectLocation.setup setup file does not exist" "Tests the logicalmerge command with an incorrect path to the setup file"|| true
+
+assertCommandOutput "git logicalmerge ../setup.setup fakeRef" 128 "fatal: fakeRef - not a valid git reference." "Tests the logicalmerge command with an incorrect commit id"|| true
+
+assertCommandOutput "git logicalmerge ../setup.setup master" 0 "Already up to date" "Tests the logicalmerge command with correct reference"|| true
+
+assertCommandOutput "git logicalmerge ../setup.setup $commitId" 0 "Already up to date" "Tests the logicalmerge command with correct commit id" || true
+
+# Changes the current directory in order not to be in a git repository
+goToWorkspace
+
+assertCommandOutput "git logicalmerge setup.setup $commitId" 128 "fatal: Can't find git repository" "Tests the logicalmerge outside a git repository scope" || true
+
+########################################## Starts testing the logicaldiff command ##########################################################
+
+goToRepoRoot
+
+expectedOut="fatal: Argument \"<setup>\" is required in:
+
+logicaldiff <setup> <commit> [<compareWithCommit>] [-- <path...>] [--help (-h)]
+
+ <setup> : Path to the setup file. The setup file is a Oomph model
+ <commit> : Commit ID or branch name
+ <compareWithCommit> : Commit ID or branch name. This is to view the changes
+ between <commit> and <compareWithCommit> or HEAD if not
+ specified.
+ -- <path...> : This is used to limit the diff to the named paths (you
+ can give directory names and get diff for all files
+ under them).
+ --help (-h) : Dispays help for this command"
+
+assertCommandOutput "git logicaldiff" 128 "$expectedOut" "Tests the logicaldiff command without any argument"|| true
+
+assertCommandOutput "git logicaldiff ../setup.setup fakeRef" 128 "fatal: fakeRef - not a valid git reference." "Tests the logicaldiff command with an incorrect commit id" || true
+
+assertCommandOutput "git logicaldiff ../setup.setup master" 0 "" "Tests the logicaldiff command with the current branch"|| true
+
+assertCommandOutput "git logicaldiff ../setup.setup $commitId" 0 "" "Tests the logicaldiff command with current commit id" || true
+
+# Changes the current directory in order not to be in a git repository
+goToWorkspace
+
+assertCommandOutput "git logicaldiff setup.setup $commitId" 128 "fatal: Can't find git repository" "Tests the logicaldiff outside a git repository scope" || true
+
+########################################## Starts testing the logicalmergetool command ##########################################
+
+goToRepoRoot
+
+expectedOut="fatal: Argument \"<setup>\" is required in:
+
+logicalmergetool <setup> [--help (-h)]
+
+ <setup> : Path to the setup file. The setup file is a Oomph model
+ --help (-h) : Dispays help for this command"
+
+assertCommandOutput "git logicalmergetool" 128 "$expectedOut" "Tests the logicalmergetool command without any argument"|| true
+
+assertCommandOutput "git logicalmergetool ./incorectLocation.setup" 128 "fatal: ./incorectLocation.setup setup file does not exist" "Tests the logicalmergetool command with an incorrect setup file" || true
+
+assertCommandOutput "git logicalmergetool ../setup.setup" 128 "fatal: No conflict to merge" "Tests the logicalmergetool command with a correct setup file" || true
+
+# Changes current directory in order not to be in a git repository
+goToWorkspace
+
+assertCommandOutput "git logicalmergetool setup.setup" 128 "fatal: Can't find git repository" "Tests the logicalmergetool command outside a git repository scope" || true
+
+# Creates a conflict between master and conflictingBranch
+goToRepoRoot
+conflictingBranch="conflictingBranch"
+git branch $conflictingBranch > /dev/null 2>&1
+createFileInRepo "ConflictingFile.txt" "Some content"
+addAllToStageArea
+commitAndGetId "Conflicting commit on master" > /dev/null 2>&1
+
+git checkout $conflictingBranch > /dev/null 2>&1
+createFileInRepo "ConflictingFile.txt" "Any content"
+addAllToStageArea
+commitAndGetId "Conflicting commit on $conflictingBranch" > /dev/null 2>&1
+git checkout "master" > /dev/null 2>&1
+# Sets the repository to "Conflicting state"
+git merge $conflictingBranch > /dev/null 2>&1 || true # the merge fail but we want it to fail.
+
+assertCommandOutput "git logicalmergetool ../setup.setup" 0 "Should display the differences" "Normal use case" || true
+
+#clean up
+rm -rf $currentWorkspace
+
+
+echo 'End...'
+echo '***************************************************************'
\ No newline at end of file
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/manTestConfiguration.sh b/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/manTestConfiguration.sh
new file mode 100644
index 0000000..7b0584a
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.scripts/tests/manTestConfiguration.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# ====================================================================
+# Copyright (c) 2014 Obeo
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+# ====================================================================
+
+
+#Location of the current script
+scriptLocation="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+echo "Exporting application varaible"
+# If the test in run on a linux gtk x86_64
+# TODO improve this
+export EMF_COMPARE_GIT_PGM_PATH="$scriptLocation/../../org.eclipse.emf.compare.git.pgm.product/target/products/org.eclipse.emf.compare.git.pgm.product/linux/gtk/x86_64/emfcompare-git-pgm"
+
+# Adds the location of the folder holding git scripts to the path. This way the command "git SCRIPT_NAME ARGS" will work.
+PATH=$scriptLocation/..:$PATH
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.update/.project b/packaging/org.eclipse.emf.compare.git.pgm.update/.project
new file mode 100644
index 0000000..5034968
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.update/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.compare.git.pgm.update</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.UpdateSiteBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.UpdateSiteNature</nature>
+ </natures>
+</projectDescription>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.update/category.xml b/packaging/org.eclipse.emf.compare.git.pgm.update/category.xml
new file mode 100644
index 0000000..2181944
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.update/category.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+ <feature url="features/org.eclipse.emf.compare.git.pgm.feature_1.0.0.qualifier.jar" id="org.eclipse.emf.compare.git.pgm.feature" version="1.0.0.qualifier"/>
+</site>
diff --git a/packaging/org.eclipse.emf.compare.git.pgm.update/pom.xml b/packaging/org.eclipse.emf.compare.git.pgm.update/pom.xml
new file mode 100644
index 0000000..dfb40ab
--- /dev/null
+++ b/packaging/org.eclipse.emf.compare.git.pgm.update/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../org.eclipse.emf.compare.git.pgm.parent/</relativePath>
+ </parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.update</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-repository</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-repository-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <repositoryName>EMF Compare EGit PGM</repositoryName>
+ <finalName>${project.groupId}-${unqualifiedVersion}.${buildQualifier}</finalName>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.classpath b/plugins/org.eclipse.emf.compare.git.pgm.tests/.classpath
new file mode 100644
index 0000000..eca7bdb
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.project b/plugins/org.eclipse.emf.compare.git.pgm.tests/.project
new file mode 100644
index 0000000..0a49080
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.compare.git.pgm.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/edu.umd.cs.findbugs.core.prefs b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/edu.umd.cs.findbugs.core.prefs
new file mode 100644
index 0000000..1fab655
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/edu.umd.cs.findbugs.core.prefs
@@ -0,0 +1,132 @@
+#FindBugs User Preferences
+#Tue Mar 12 08:11:54 CET 2013
+cloud_id=edu.umd.cs.findbugs.cloud.doNothingCloud
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorAtomicityProblem=AtomicityProblem|true
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false
+detectorCheckExpectedWarnings=CheckExpectedWarnings|false
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|true
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDefaultEncodingDetector=DefaultEncodingDetector|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorExplicitSerialization=ExplicitSerialization|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUseOfNonSerializableValue=FindUseOfNonSerializableValue|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInitializeNonnullFieldsInConstructor=InitializeNonnullFieldsInConstructor|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorIntCast2LongAsInstant=IntCast2LongAsInstant|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false|15
+filter_settings_neg=NOISE,I18N,EXPERIMENTAL|
+run_at_full_build=true
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs
new file mode 100644
index 0000000..4235f76
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+edu.umd.cs.findbugs.plugin.eclipse.findbugsMarkerScariest=Error
+edu.umd.cs.findbugs.plugin.eclipse.findbugsMarkerScary=Error
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.core.runtime.prefs b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..42d105e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,375 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis=disabled
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=110
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=110
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=false
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..4e1442e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,60 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_EMF Compare
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=fr;com;java;javax;org;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.pde.api.tools.prefs b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..01461e0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,97 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Warning
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Warning
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Warning
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Warning
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Warning
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Warning
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Warning
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Warning
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Warning
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Warning
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Warning
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Warning
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Warning
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Warning
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Warning
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Warning
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Warning
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Warning
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Warning
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Warning
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Warning
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Warning
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Warning
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Warning
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Warning
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Warning
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Warning
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+MISSING_EE_DESCRIPTIONS=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Warning
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Warning
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Warning
+malformed_since_tag=Warning
+missing_since_tag=Warning
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.git.pgm.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..98bd117
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Fragment-Host: org.eclipse.emf.compare.git.pgm;bundle-version="1.0.0"
+Bundle-Name: EMF Compare Git PGM Tests
+Bundle-SymbolicName: org.eclipse.emf.compare.git.pgm.tests;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.junit;bundle-version="4.11.0",
+ org.eclipse.team.core;bundle-version="3.0.0",
+ org.eclipse.jgit;bundle-version="3.4.0",
+ org.eclipse.egit.core;bundle-version="3.4.0",
+ org.eclipse.oomph.util;bundle-version="1.0.0",
+ org.eclipse.oomph.base.edit;bundle-version="1.0.0",
+ org.eclipse.oomph.setup;bundle-version="1.0.0",
+ org.eclipse.oomph.setup.core;bundle-version="1.0.0",
+ org.eclipse.emf.compare;bundle-version="3.1.0",
+ org.eclipse.emf.compare.ide.ui;bundle-version="4.0.0"
+Import-Package: com.google.common.collect;version="[15.0.0,15.0.0]",
+ com.google.common.io;version="[15.0.0,15.0.0]"
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/READ-ME b/plugins/org.eclipse.emf.compare.git.pgm.tests/READ-ME
new file mode 100644
index 0000000..6292605
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/READ-ME
@@ -0,0 +1,4 @@
+WARNING
+If you want to run the tests inside your IDE please select in your run configuration in main tab:
+* The application name "[No Application] - Headless mode"
+* JavaSE-1.8 as Execution Environment
\ No newline at end of file
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/build.properties b/plugins/org.eclipse.emf.compare.git.pgm.tests/build.properties
new file mode 100644
index 0000000..c4a0595
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/build.properties
@@ -0,0 +1,16 @@
+# Copyright (c) 2014 Obeo.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Obeo - initial API and implementation
+
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ model/
+jre.compilation.profile = J2SE-1.5
+src.includes = model/
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/model/lunaIntegrationTest.setup b/plugins/org.eclipse.emf.compare.git.pgm.tests/model/lunaIntegrationTest.setup
new file mode 100644
index 0000000..33a76bd
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/model/lunaIntegrationTest.setup
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<setup:Index
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:setup="http://www.eclipse.org/oomph/setup/1.0"
+ xmlns:setup.p2="http://www.eclipse.org/oomph/setup/p2/1.0"
+ name="org.eclipse"
+ label="Eclipse.org">
+ <productCatalog
+ name="org.eclipse.products"
+ label="Eclipse.org">
+ <setupTask
+ xsi:type="setup.p2:P2Task"
+ id="P2 oomph"
+ licenseConfirmationDisabled="true">
+ <requirement
+ name="org.eclipse.emf.sdk.feature.group"/>
+ <requirement
+ name="org.eclipse.egit"/>
+ <requirementfile
+ name="org.eclipse.egit.core"/>
+ <requirement
+ name="org.eclipse.pde.api.tools.ee.feature.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.core.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.jdt.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.git.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.projects.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.p2.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.version.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.projectcopy.feature.group"/>
+ <requirement
+ name="org.eclipse.emf.compare.feature.group"/>
+ <requirement
+ name="org.eclipse.emf.compare.ide.ui.feature.group"/>
+ <requirement
+ name="org.kohsuke.args4j"/>
+ <requirement
+ name="com.google.guava"/>
+ <requirement
+ name="org.eclipse.emf.compare.git.pgm.feature.feature.group"/>
+ <repository
+ url="http://download.eclipse.org/releases/luna/201406250900"/>
+ <repository
+ url="http://ericssonegit.ci.obeo.fr:8180/jenkins/job/egit-logical/lastSuccessfulBuild/artifact/org.eclipse.egit.repository/target/repository/"/>
+ <repository
+ url="${emfcompare-git-pgm--updasite}"/>
+ <repository
+ url="http://download.eclipse.org/modeling/emf/emf/updates/2.10/core/R201405190339"/>
+ <repository
+ url="https://hudson.eclipse.org/oomph/job/integration/lastSuccessfulBuild/artifact/updates/"/>
+ <repository
+ url="http://download.eclipse.org/modeling/emf/compare/updates/nightly/latest"/>
+ <repository
+ url="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/"/>
+ </setupTask>
+ <product
+ name="epp.package.standard"
+ label="Eclipse Standard/SDK">
+ <version
+ name="luna"
+ label="Luna">
+ <setupTask
+ xsi:type="setup.p2:P2Task"
+ id="P2 Eclipse"
+ licenseConfirmationDisabled="true">
+ <requirement
+ name="epp.package.standard"
+ versionRange="[4.4.0,4.5.0)"/>
+ <requirement
+ name="org.eclipse.platform.feature.group"
+ versionRange="[4.4.0,4.5.0)"/>
+ <requirement
+ name="org.eclipse.rcp.feature.group"
+ versionRange="[4.4.0,4.5.0)"/>
+ <requirement
+ name="org.eclipse.jdt.feature.group"
+ versionRange="[3.10.0,3.11.0)"/>
+ <requirement
+ name="org.eclipse.pde.feature.group"
+ versionRange="[3.9.0,3.11.0)"/>
+ <repository
+ url="http://download.eclipse.org/technology/epp/packages/luna"/>
+ <repository
+ url="http://download.eclipse.org/releases/luna/201406250900"/>
+ </setupTask>
+ </version>
+ </product>
+ <description>All the Eclipse Packaging Products at Eclipse.org</description>
+ </productCatalog>
+</setup:Index>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/pom.xml b/plugins/org.eclipse.emf.compare.git.pgm.tests/pom.xml
new file mode 100644
index 0000000..9699309
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/pom.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../org.eclipse.emf.compare.git.pgm.parent/</relativePath>
+ </parent>
+
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.tests</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-test-plugin</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <!-- Needed since the tests are now written with Java 8 -->
+ <executionEnvironment>JavaSE-1.8</executionEnvironment>
+ <dependency-resolution>
+ <!-- The test suite AllApplicationTest needs a provisioned platform
+ with the following components. Below is new way to force those components
+ to be installed in the runtime test platform since tycho 0.21.0. For more
+ information see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=436617#c11,
+ https://bugs.eclipse.org/bugs/show_bug.cgi?id=438559, http://comments.gmane.org/gmane.comp.ide.eclipse.tycho.user/4154 -->
+ <extraRequirements>
+ <requirement>
+ <type>eclipse-feature</type>
+ <id>org.eclipse.emf.compare.uml2</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>eclipse-feature</type>
+ <id>org.eclipse.emf.compare.ide.ui</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>eclipse-feature</type>
+ <id>org.eclipse.uml2</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>eclipse-feature</type>
+ <id>org.eclipse.gmf.runtime.notation</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>eclipse-feature</type>
+ <id>org.eclipse.emf.compare.diagram.papyrus</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>eclipse-feature</type>
+ <id>org.eclipse.egit</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.core.net</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.equinox.ds</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>eclipse-feature</type>
+ <id>org.eclipse.equinox.p2.core.feature</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.equinox.ds</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.oomph.util</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.oomph.base.edit</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.oomph.setup</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.oomph.setup.core</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.oomph.setup.projects</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.oomph.setup.p2</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+ <requirement>
+ <type>p2-installable-unit</type>
+ <id>org.eclipse.platform.sdk</id>
+ <versionRange>0.0.0</versionRange>
+ </requirement>
+
+ </extraRequirements>
+ </dependency-resolution>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-surefire-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <application>org.eclipse.pde.junit.runtime.coretestapplication</application>
+ <useUIHarness>false</useUIHarness>
+ <useUIThread>false</useUIThread>
+ <includes>
+ <include>org/eclipse/emf/compare/git/pgm/suite/AllIntegrationTests.java</include>
+ <include>org/eclipse/emf/compare/git/pgm/suite/AllCommandLineArguementTests.java</include>
+ <include>org/eclipse/emf/compare/git/pgm/suite/AllLogicalApplicationTests.java</include>
+ <include>org/eclipse/emf/compare/git/pgm/suite/AllUtilTests.java</include>
+ </includes>
+ <systemProperties>
+ <!-- Point to the location to the newly created update. This property
+ is need for the model/lunaIntegrationTest.setup -->
+ <emfcompare-git-pgm--updasite>${project.baseUri}../../packaging/org.eclipse.emf.compare.git.pgm.update/target/repository/</emfcompare-git-pgm--updasite>
+ </systemProperties>
+
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/AbstractApplicationTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/AbstractApplicationTest.java
new file mode 100644
index 0000000..1942479
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/AbstractApplicationTest.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EMPTY_STRING;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileAttribute;
+import java.util.List;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.emf.compare.git.pgm.util.MockedApplicationContext;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.CheckoutConflictException;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.InvalidRefNameException;
+import org.eclipse.jgit.api.errors.NoFilepatternException;
+import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.api.errors.NoMessageException;
+import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
+import org.eclipse.jgit.api.errors.RefNotFoundException;
+import org.eclipse.jgit.api.errors.UnmergedPathsException;
+import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public abstract class AbstractApplicationTest {
+ private static final String TMP_DIRECTORY_PREFIX = "emfcompare-git-pgm"; //$NON-NLS-1$
+
+ private static final String REPO_PREFIX = "Repo_"; //$NON-NLS-1$
+
+ private Path testTmpFolder;
+
+ private IApplication app;
+
+ private MockedApplicationContext context;
+
+ private Path repositoryPath;
+
+ private File gitFolderPath;
+
+ private ByteArrayOutputStream outputStream;
+
+ private ByteArrayOutputStream errStream;
+
+ private Git git;
+
+ private String userDir;
+
+ private PrintStream sysout;
+
+ private PrintStream syserr;
+
+ /**
+ * Internal data structure.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+ protected static class CommittedFile {
+ private final File file;
+
+ private final RevCommit rev;
+
+ public CommittedFile(File file, RevCommit rev) {
+ super();
+ this.file = file;
+ this.rev = rev;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public RevCommit getRev() {
+ return rev;
+ }
+ }
+
+ @Before
+ public void before() throws Exception {
+ // Creates a local git repository for test purpose
+ testTmpFolder = Files.createTempDirectory(TMP_DIRECTORY_PREFIX, new FileAttribute<?>[] {});
+ outputStream = new ByteArrayOutputStream();
+ errStream = new ByteArrayOutputStream();
+ sysout = System.out;
+ syserr = System.err;
+
+ // Redirects out and err in order to test outputs.
+ System.setOut(new PrintStream(outputStream));
+ System.setErr(new PrintStream(errStream));
+
+ app = buildApp();
+ setContext(new MockedApplicationContext());
+
+ setRepositoryPath(Files.createTempDirectory(testTmpFolder, REPO_PREFIX, new FileAttribute<?>[] {}));
+ setGitFolderPath(new File(getRepositoryPath().toFile(), Constants.DOT_GIT));
+ git = Git.init().setDirectory(getRepositoryPath().toFile()).call();
+ // Saves the user.dire property to be able to restore it.( some tests can modify it)
+ userDir = System.getProperty("user.dir"); //$NON-NLS-1$
+
+ }
+
+ protected File getWorkspaceLocation() {
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceRoot root = workspace.getRoot();
+ return root.getLocation().toFile();
+ }
+
+ protected abstract IApplication buildApp();
+
+ @After
+ public void tearDown() throws Exception {
+ // repository.dispose();
+ git.close();
+ // Restores system properties
+ setCmdLocation(userDir);
+
+ File tmpFolder = testTmpFolder.toFile();
+ if (tmpFolder.exists()) {
+ FileUtils.delete(tmpFolder, FileUtils.RECURSIVE | FileUtils.RETRY);
+ }
+
+ System.setOut(sysout);
+ outputStream.close();
+
+ System.setErr(syserr);
+ errStream.close();
+
+ }
+
+ protected void setCmdLocation(String path) {
+ System.setProperty("user.dir", path); //$NON-NLS-1$
+ }
+
+ protected void assertOutputMessageEnd(String expected) {
+ String outputStreamContent = outputStream.toString();
+ // -1 since we want to keep empty lines
+ List<String> expectedLines = Lists.newArrayList(expected.split(EOL, -1));
+ List<String> actualLines = Lists.newArrayList(outputStreamContent.split(EOL, -1));
+ List<String> actualEndingLine = actualLines.subList(actualLines.size() - expectedLines.size(),
+ actualLines.size());
+ for (int i = 0; i < expectedLines.size(); i++) {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("The line number ").append(i).append(
+ " of the actual message did not match the related line in expected message:").append(EOL);
+ stringBuilder.append(expected).append(EOL);
+ stringBuilder.append("Actual:").append(EOL);
+ stringBuilder.append(Joiner.on(EOL).join(actualEndingLine)).append(EOL);
+ assertEquals(stringBuilder.toString(), expectedLines.get(i), actualEndingLine.get(i));
+ }
+ }
+
+ protected void assertEmptyErrorMessage() {
+ assertEquals(EMPTY_STRING, errStream.toString());
+ }
+
+ protected void assertOutput(String message) {
+ assertEquals(message, outputStream.toString());
+ }
+
+ protected Path getTestTmpFolder() {
+ return testTmpFolder;
+ }
+
+ protected IApplication getApp() {
+ return app;
+ }
+
+ protected RevCommit addAllAndCommit(String commitMessage) throws GitAPIException, NoFilepatternException,
+ NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException,
+ WrongRepositoryStateException {
+ DirCache dirChache = git.add().addFilepattern(".").call(); //$NON-NLS-1$
+ // Assert there is something to commit
+ assertTrue(dirChache.getEntriesWithin("").length > 0);
+ RevCommit revCommit = git.commit().setAuthor("Logical test author", "logicaltest@obeo.fr")
+ .setCommitter("Logical test author", "logicaltest@obeo.fr").setMessage(commitMessage).call();
+ return revCommit;
+ }
+
+ protected Ref createBranch(String branchName, String startingPoint) throws RefAlreadyExistsException,
+ RefNotFoundException, InvalidRefNameException, GitAPIException {
+ return getGit().branchCreate().setName(branchName).setStartPoint(startingPoint).call();
+ }
+
+ protected Ref createBranchAndCheckout(String ref, String startingPoint) throws RefAlreadyExistsException,
+ RefNotFoundException, InvalidRefNameException, CheckoutConflictException, GitAPIException {
+ return getGit().checkout().setName(ref).setStartPoint(startingPoint).setCreateBranch(true).call();
+ }
+
+ protected Git getGit() {
+ return git;
+ }
+
+ protected void printOut() {
+ sysout.println(outputStream.toString());
+ }
+
+ protected void printErr() {
+ syserr.println(errStream.toString());
+ }
+
+ protected String getConfigurationMessage() throws IOException {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Configuration:").append(EOL);
+ builder.append("\t").append("Tmp folder: ").append(testTmpFolder.toString()).append(EOL);
+ builder.append("\t").append("Git folder: ").append(gitFolderPath.getAbsolutePath()).append(EOL);
+ builder.append("\t").append("Git content:").append(EOL);
+ Files.walkFileTree(repositoryPath, new FileVisitor<Path>() {
+
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+ if (dir.endsWith(".git")) {
+ return FileVisitResult.SKIP_SUBTREE;
+ } else {
+ builder.append("\t\t").append(dir.toString()).append(EOL);
+ return FileVisitResult.CONTINUE;
+ }
+ }
+
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+
+ return builder.toString();
+ }
+
+ public MockedApplicationContext getContext() {
+ return context;
+ }
+
+ public void setContext(MockedApplicationContext context) {
+ this.context = context;
+ }
+
+ public Path getRepositoryPath() {
+ return repositoryPath;
+ }
+
+ public void setRepositoryPath(Path repositoryPath) {
+ this.repositoryPath = repositoryPath;
+ }
+
+ public File getGitFolderPath() {
+ return gitFolderPath;
+ }
+
+ public void setGitFolderPath(File gitFolderPath) {
+ this.gitFolderPath = gitFolderPath;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/AbstractLogicalAppTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/AbstractLogicalAppTest.java
new file mode 100644
index 0000000..63122bd
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/AbstractLogicalAppTest.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm;
+
+import org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommand;
+import org.eclipse.equinox.app.IApplication;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public abstract class AbstractLogicalAppTest extends AbstractApplicationTest {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.AbstractApplicationTest#buildApp()
+ */
+ @Override
+ protected IApplication buildApp() {
+ return new LogicalApp();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.AbstractApplicationTest#getApp()
+ */
+ @Override
+ protected LogicalApp getApp() {
+ return (LogicalApp)super.getApp();
+ }
+
+ protected AbstractLogicalCommand getLogicalCommand() {
+ return getApp().getLogicalCommand();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/LogicalAppTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/LogicalAppTest.java
new file mode 100644
index 0000000..722d4ff
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/LogicalAppTest.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Test class for the main application.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalAppTest extends AbstractLogicalAppTest {
+
+ private String getExpectedAvailableCommandUsage() {
+ //@formatter:off
+ return EOL
+ + "Available commands are:" + EOL
+ + "logicaldiff" + EOL
+ + "logicalmerge" + EOL
+ + "logicalmergetool" + EOL;
+ //@formatter:on
+ }
+
+ private String getExpectedUsage() {
+ //@formatter:off
+ return "logicalApp --help (-h) command [ARG ...]" + EOL
+ + EOL //
+ + " --help (-h) : Displays help for this command." + EOL;
+ //@formatter:on
+ }
+
+ @Test
+ public void helpTest() throws Exception {
+ getContext().addArg("--help");
+ Object result = getApp().start(getContext());
+ assertEquals(Returns.COMPLETE, result);
+ String expectMessage = getExpectedUsage() + getExpectedAvailableCommandUsage(); //
+ assertOutput(expectMessage);
+ assertEmptyErrorMessage();
+ }
+
+ @Test
+ public void noArgumentTest() throws Exception {
+ Object result = getApp().start(getContext());
+ String extectedOut = "fatal: logicalApp --help (-h) command [ARG ...]" + EOL//
+ + getExpectedAvailableCommandUsage() //
+ + EOL;
+ assertOutput(extectedOut);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+
+ }
+
+ @Test
+ public void wrongOptTest() throws Exception {
+ getContext().addArg("-c");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: \"-c\" is not a valid option" + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void wrongCmdTest() throws Exception {
+ getContext().addArg("wrongCmd");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: Not a logical command wrongCmd" + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalDiffApplicationTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalDiffApplicationTest.java
new file mode 100644
index 0000000..b475f33
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalDiffApplicationTest.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.app;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import org.eclipse.emf.compare.git.pgm.AbstractApplicationTest;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.eclipse.equinox.app.IApplication;
+import org.junit.Test;
+
+/**
+ * Tests the logical diff application.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class LogicalDiffApplicationTest extends AbstractApplicationTest {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.AbstractApplicationTest#buildApp()
+ */
+ @Override
+ protected IApplication buildApp() {
+ return new LogicalDiffApplication();
+ }
+
+ /**
+ * Test if there is no difference to display then the software display the "No differende to display"
+ * message.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void nothingToDo() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(getTestTmpFolder().resolve("oomphFolder").toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // No reference
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), newSetupFile.getAbsolutePath(),
+ "master", "master");
+ Object result = getApp().start(getContext());
+ assertOutputMessageEnd("No difference to display." + EMFCompareGitPGMUtil.EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalMergeApplicationTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalMergeApplicationTest.java
new file mode 100644
index 0000000..fbfce36
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalMergeApplicationTest.java
@@ -0,0 +1,1159 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.app;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.CURRENT;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.PARENT;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.SEP;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Sets;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.git.pgm.AbstractApplicationTest;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalMergeApplicationTest extends AbstractApplicationTest {
+
+ /**
+ * <h3>Test the logical merge application on the current branch</h3>
+ * <p>
+ * This use case aims to produce a "Already up to date message".
+ * </p>
+ * <h3>History:</h3>
+ *
+ * <pre>
+ * Initial commit (PapyrusProject3) [Master]
+ * </pre>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void alreadyUpToDate0() throws Exception {
+ Path projectPath = getRepositoryPath().resolve("PapyrusModel");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.notation") //
+ .create(projectPath);
+ RevCommit rev = addAllAndCommit("Initial commit [PapyrusProject3]");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ "master");
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ // printOut();
+ // printErr();
+
+ assertTrue(getGit().status().call().isClean());
+ assertEquals(getGit().getRepository().resolve("HEAD").getName(), rev.getId().getName());
+ assertOutputMessageEnd("Already up to date." + EOL + EOL);
+ assertEquals(Returns.COMPLETE.code(), result);
+
+ }
+
+ /**
+ * <h3>Test the logical application on previous commit of the current branch</h3> <h3>History:</h3>
+ *
+ * <pre>
+ * * Adds Class 1 [branch_b]
+ * |
+ * |
+ * Initial commit (PapyrusProject3) [branch_a]
+ *
+ * </pre>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void alreadyUpToDate1() throws Exception {
+ Path projectPath = getRepositoryPath().resolve("PapyrusModel");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.notation") //
+ .create(projectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ // Creates branch b
+ String branchB = "branch_b";
+ createBranchAndCheckout(branchB, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/automerging/MER003/branch_b/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_b/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_b/model.notation") //
+ .create(projectPath);
+
+ RevCommit commitB = addAllAndCommit("Adds class 1");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is launched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchA);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ assertOutputMessageEnd("Already up to date." + EOL + EOL);
+ assertEquals(Returns.COMPLETE.code(), result);
+
+ assertTrue(getGit().status().call().isClean());
+ assertEquals(getGit().getRepository().resolve("HEAD").getName(), commitB.getId().getName());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.AbstractApplicationTest#buildApp()
+ */
+ @Override
+ protected IApplication buildApp() {
+ return new LogicalMergeApplication();
+ }
+
+ /**
+ * Create a Oomph setup file being able to handle the merge of a Papyrus model.
+ *
+ * @param project
+ * @return
+ * @throws IOException
+ */
+ private File createPapyrusUserOomphModel(File... project) throws IOException {
+ return createPapyrusUserOomphModel(getTestTmpFolder().resolve("setup.setup"), project);
+ }
+
+ private File createPapyrusUserOomphModel(Path setupFilePath, File... project) throws IOException {
+ OomphUserModelBuilder userModelBuilder = new OomphUserModelBuilder();
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File userSetupFile = userModelBuilder.setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(getWorkspaceLocation().getAbsolutePath()) //
+ .setProjectPaths(Arrays.stream(project).map(p -> p.getAbsolutePath()).toArray(String[]::new)) //
+ .setRepositories("http://download.eclipse.org/releases/luna/201406250900",
+ "http://download.eclipse.org/modeling/emf/compare/updates/nightly/latest/") //
+ .setRequirements("org.eclipse.uml2.feature.group",
+ "org.eclipse.papyrus.sdk.feature.feature.group",
+ "org.eclipse.emf.compare.rcp.ui.feature.group",
+ "org.eclipse.emf.compare.uml2.feature.group",
+ "org.eclipse.emf.compare.diagram.gmf.feature.group",
+ "org.eclipse.emf.compare.diagram.papyrus.feature.group") //
+ .saveTo(setupFilePath.toString());
+ return userSetupFile;
+ }
+
+ /**
+ * Assert that there is no conflict marker in the file (( <<<<<<<<<< or ========= or >>>>>>>>>>>). In fact
+ * this test try to load the resource.
+ *
+ * @param paths
+ * @throws IOException
+ * @throws AssertionError
+ */
+ private void assertNoConflitMarker(Path... paths) throws AssertionError, IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ for (Path p : paths) {
+ try {
+ Resource resource = resourceSet.getResource(URI.createFileURI(p.toString()), true);
+ assertNotNull(resource);
+ } catch (Exception e) {
+ throw new AssertionError("Error wile parsing resource " + p.toString() + EOL
+ + getConfigurationMessage(), e);
+ }
+ }
+ }
+
+ private void assertExistInResource(Path resourcePath, String... fragments) throws IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ Resource resource = resourceSet.getResource(URI.createFileURI(resourcePath.toString()), true);
+ assertNotNull(resource);
+ for (String fragment : fragments) {
+ EObject eObject = resource.getEObject(fragment);
+ assertNotNull("Element with framgment " + fragment + " does not exist" + EOL
+ + getConfigurationMessage(), eObject);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.AbstractApplicationTest#getApp()
+ */
+ @Override
+ protected LogicalMergeApplication getApp() {
+ return (LogicalMergeApplication)super.getApp();
+ }
+
+ // @Test
+ // public void incorrectOomphSetupFile_NoExistingProject() throws Exception {
+ // Path projectPath = getRepositoryPath().resolve("AProject");
+ // File project = new ProjectBuilder(this) //
+ // .addNewFileContent("ATextFile.txt", "SomeContent").create(projectPath);
+ // String branchA = "branch_a";
+ // addAllAndCommit("Initial commit");
+ // createBranch(branchA, "master");
+ //
+ // getGit().close();
+ //
+ // // Creates Oomph model
+ // File userSetupFile = createPapyrusUserOomphModel(getRepositoryPath().resolve("NonExistingProject")
+ // .toFile());
+ //
+ // // Mocks that the commands is lauched from the git repository folder.
+ // setCmdLocation(getRepositoryPath().toString());
+ //
+ // // Sets args
+ // getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ // branchA);
+ //
+ // // Runs command
+ // Object result = getApp().start(getContext());
+ //
+ // // Uncomments to displays output
+ // printOut();
+ // printErr();
+ //
+ // // IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ // // assertEquals(1, projectInWorkspace.length);
+ // //
+ // // assertEquals(Returns.ABORTED.code(), result);
+ // //
+ // // StringBuilder expectedOut = new StringBuilder();
+ // // expectedOut.append("Auto-merging failed in ").append("MER001/model.notation").append(EOL);
+ // // expectedOut.append("Auto-merging failed in ").append("MER001/model.uml").append(EOL);
+ // // expectedOut.append("Automatic merge failed; fix conflicts and then commit the result.").append(EOL)
+ // // .append(EOL);
+ // // assertOutputMessageEnd(expectedOut.toString());
+ // //
+ // // assertNoConflitMarker(projectPath.resolve("model.uml"), projectPath.resolve("model.notation"));
+ // //
+ // // Set<String> expectedConflictingFilePath = Sets
+ // // .newHashSet("MER001/model.uml", "MER001/model.notation");
+ // // assertEquals(expectedConflictingFilePath, getGit().status().call().getConflicting());
+ // }
+
+ /**
+ * <h3>Use case MER001</h3>
+ * <p>
+ * This use case is used to achive a conflicting merge
+ * </p>
+ *
+ * <pre>
+ * * Delete Class1 [branch_c]
+ * |
+ * | * Add Attribute1 under Class1 [branch_b]
+ * |/
+ * |
+ * Initial Commit [branch_a]
+ * -Add project PapyrusProject1
+ * -Add ClassDiagram1
+ * -Add Class1
+ *
+ * </pre>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMER001() throws Exception {
+
+ Path projectPath = getRepositoryPath().resolve("MER001");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/conflicts/MER001/branch_a/model.di")//
+ .addContentToCopy("data/conflicts/MER001/branch_a/model.uml") //
+ .addContentToCopy("data/conflicts/MER001/branch_a/model.notation") //
+ .create(projectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ // Creates branch c
+ String branchC = "branch_c";
+ createBranchAndCheckout(branchC, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER001/branch_c/model.di")//
+ .addContentToCopy("data/conflicts/MER001/branch_c/model.uml") //
+ .addContentToCopy("data/conflicts/MER001/branch_c/model.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Deletes Class1");
+
+ // Creates branch b
+ String branchB = "branch_b";
+ createBranchAndCheckout(branchB, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER001/branch_b/model.di")//
+ .addContentToCopy("data/conflicts/MER001/branch_b/model.uml") //
+ .addContentToCopy("data/conflicts/MER001/branch_b/model.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Adds attribute1 under Class1");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchC);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertEquals(Returns.ABORTED.code(), result);
+
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("Auto-merging failed in ").append("MER001/model.notation").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER001/model.uml").append(EOL);
+ expectedOut.append("Automatic merge failed; fix conflicts and then commit the result.").append(EOL)
+ .append(EOL);
+ assertOutputMessageEnd(expectedOut.toString());
+
+ assertNoConflitMarker(projectPath.resolve("model.uml"), projectPath.resolve("model.notation"));
+
+ Set<String> expectedConflictingFilePath = Sets
+ .newHashSet("MER001/model.uml", "MER001/model.notation");
+ assertEquals(expectedConflictingFilePath, getGit().status().call().getConflicting());
+ }
+
+ /**
+ * <h3>Test use case MER002</h3>
+ * <p>
+ * This aims to test a merge between two branches with more than commit between them (see history)
+ * </p>
+ * <h3>History</h3>
+ *
+ * <pre>
+ * * Delete Class2 [branch_d]
+ * |
+ * |
+ * Delete Class1 [branc_c]
+ * |
+ * |
+ * | * Add attribute1 under Class1, attribute2 under Class2 [branch_b]
+ * |/
+ * |
+ * |
+ * Initial Commit [branch_a]
+ * -Add project PapyrusProject2
+ * -Add ClassDiagram1
+ * -Add Class1, Class2
+ *
+ * </pre>
+ */
+ @Test
+ public void testMER002() throws Exception {
+ Path projectPath = getRepositoryPath().resolve("MER002");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/conflicts/MER002/branch_a/model.di")//
+ .addContentToCopy("data/conflicts/MER002/branch_a/model.uml") //
+ .addContentToCopy("data/conflicts/MER002/branch_a/model.notation") //
+ .create(projectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ // Creates branch c
+ String branchC = "branch_c";
+ createBranchAndCheckout(branchC, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER002/branch_c/model.di")//
+ .addContentToCopy("data/conflicts/MER002/branch_c/model.uml") //
+ .addContentToCopy("data/conflicts/MER002/branch_c/model.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Deletes Class1");
+
+ // Creates branch d
+ String branchD = "branch_d";
+ createBranchAndCheckout(branchD, branchC);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER002/branch_c/model.di")//
+ .addContentToCopy("data/conflicts/MER002/branch_c/model.uml") //
+ .addContentToCopy("data/conflicts/MER002/branch_c/model.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Delete Class2");
+
+ // Creates branch b
+ String branchB = "branch_b";
+ createBranchAndCheckout(branchB, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER002/branch_b/model.di")//
+ .addContentToCopy("data/conflicts/MER002/branch_b/model.uml") //
+ .addContentToCopy("data/conflicts/MER002/branch_b/model.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Add attribute1 under Class1, attribute2 under Class2");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchD);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertEquals(Returns.ABORTED.code(), result);
+
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("Auto-merging failed in ").append("MER002/model.notation").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER002/model.uml").append(EOL);
+ expectedOut.append("Automatic merge failed; fix conflicts and then commit the result.").append(EOL)
+ .append(EOL);
+ assertOutputMessageEnd(expectedOut.toString());
+
+ assertNoConflitMarker(projectPath.resolve("model.uml"), projectPath.resolve("model.notation"));
+
+ Set<String> expectedConflictingFilePath = Sets
+ .newHashSet("MER002/model.uml", "MER002/model.notation");
+ assertEquals(expectedConflictingFilePath, getGit().status().call().getConflicting());
+
+ }
+
+ /**
+ * <h3>Test with a setup file that references incorrect projects.</h3>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testIncorrectProjectToImport_NotExistingProject() throws Exception {
+ Path existinProjectPath = getRepositoryPath().resolve("MER003");
+ File existingProject = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.notation") //
+ .create(existinProjectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ File notExistinProject = getRepositoryPath().resolve("GhostProject").toFile();
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(existingProject, notExistinProject);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchA);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("fatal: Projects Import Analysis Projects Import Analysis of '").append(
+ notExistinProject.getAbsolutePath()).append("'").append(EOL);
+ expectedOut.append(" The root folder '").append(notExistinProject.getAbsolutePath()).append(
+ "' doesn't exist").append(EOL).append(EOL);
+
+ assertOutputMessageEnd(expectedOut.toString());
+ assertEquals(Returns.ERROR.code(), result);
+
+ }
+
+ /**
+ * Test importing a project with a real complexe path.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testProjectToImport_complexPath() throws Exception {
+ Path folderWithComplexePath = getRepositoryPath().resolve("Folder with space & special char");
+ folderWithComplexePath.toFile().mkdirs();
+ Path existinProjectPath = folderWithComplexePath.resolve("Project with path and spécial character");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.notation") //
+ .create(existinProjectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchA);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertEquals(Returns.COMPLETE.code(), result);
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("Performing setup task Projects Import Task").append(EOL);
+ expectedOut.append("Importing projects from ").append(project.getAbsolutePath()).append(EOL);
+ expectedOut.append(project.toPath().getFileName().toString()).append(EOL);
+ expectedOut.append("Already up to date.");
+ }
+
+ /**
+ * Test using a setup file using a complex path
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSetupFile_complexPath() throws Exception {
+
+ Path existinProjectPath = getRepositoryPath().resolve("MER003");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.notation") //
+ .create(existinProjectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ getGit().close();
+
+ Path folderWithComplexePath = getRepositoryPath().resolve("Folder with space & special char");
+ folderWithComplexePath.toFile().mkdirs();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(folderWithComplexePath
+ .resolve("Setup file with spaces.setup"), project);
+
+ // Mocks that the commands is launched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchA);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertEquals(Returns.COMPLETE.code(), result);
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("Performing setup task Projects Import Task").append(EOL);
+ expectedOut.append("Importing projects from ").append(project.getAbsolutePath()).append(EOL);
+ expectedOut.append(project.toPath().getFileName().toString()).append(EOL);
+ expectedOut.append("Already up to date.");
+
+ }
+
+ /**
+ * Test using a setup file using a complex path
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRelativePaths() throws Exception {
+
+ Path existinProjectPath = getRepositoryPath().resolve("MER003");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.notation") //
+ .create(existinProjectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ getGit().close();
+
+ Path folder = getRepositoryPath().resolve("a" + SEP + "b" + SEP + "c");
+ folder.toFile().mkdirs();
+
+ // Creates Oomph model
+ createPapyrusUserOomphModel(folder.resolve("setup.setup"), project);
+
+ // Mocks that the commands is launched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Args : relative paths
+ String repoPathLastSegment = getRepositoryPath().toString().substring(
+ getRepositoryPath().toString().lastIndexOf(SEP) + 1);
+ String gitRelativePath = PARENT + SEP + repoPathLastSegment + SEP + ".git";
+ String setupRelativePath = CURRENT + SEP + "a" + SEP + "b" + SEP + "c" + SEP + "setup.setup";
+
+ // Sets args
+ getContext().addArg(gitRelativePath, setupRelativePath, branchA);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertEquals(Returns.COMPLETE.code(), result);
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("Performing setup task Projects Import Task").append(EOL);
+ expectedOut.append("Importing projects from ").append(project.getAbsolutePath()).append(EOL);
+ expectedOut.append(project.toPath().getFileName().toString()).append(EOL);
+ expectedOut.append("Already up to date.");
+
+ }
+
+ /**
+ * <h3>Test the use case MER003</h3>
+ * <p>
+ * This use case aims to test a logical merge on a model with no conflict (Auto merging should succeed).
+ * </p>
+ * <h3>History:</h3>
+ *
+ * <pre>
+ * * Adds Class 1 [branch_b]
+ * |
+ * | * Adds Class 2 [branch_c]
+ * |/
+ * |
+ * Initial commit (PapyrusProject3) [branch_a]
+ *
+ * </pre>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMER003() throws Exception {
+ Path projectPath = getRepositoryPath().resolve("MER003");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_a/model.notation") //
+ .create(projectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit [PapyrusProject3]");
+ createBranch(branchA, "master");
+
+ // Creates branch c
+ String branchC = "branch_c";
+ createBranchAndCheckout(branchC, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/automerging/MER003/branch_c/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_c/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_c/model.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Adds class 2");
+
+ // Creates branch b
+ String branchB = "branch_b";
+ createBranchAndCheckout(branchB, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/automerging/MER003/branch_b/model.di")//
+ .addContentToCopy("data/automerging/MER003/branch_b/model.uml") //
+ .addContentToCopy("data/automerging/MER003/branch_b/model.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Adds class 1");
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is launched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchC, "-m", "My message");
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertOutputMessageEnd("Merge made by 'recursive' strategy." + EOL + EOL);
+ assertEquals(Returns.COMPLETE.code(), result);
+
+ final String class1URIFragment = "_bB2fYC3HEeSN_5D5iyrZGQ";
+ final String class2URIFragment = "_hfIr4C3HEeSN_5D5iyrZGQ";
+ assertExistInResource(project.toPath().resolve("model.uml"), class1URIFragment, class2URIFragment);
+
+ final String class2ShapeURIFragment = "_hfJS8C3HEeSN_5D5iyrZGQ";
+ final String class1ShapeURIFragment = "_bB3tgC3HEeSN_5D5iyrZGQ";
+ assertExistInResource(project.toPath().resolve("model.notation"), class1ShapeURIFragment,
+ class2ShapeURIFragment);
+
+ Iterator<RevCommit> it = getGit().log().call().iterator();
+ RevCommit newHead = it.next();
+ assertEquals("My message", newHead.getFullMessage());
+
+ }
+
+ /**
+ * <pre>
+ * * [branch_c]
+ * | Add Class3 under Model1
+ * | Add Class4 under Model2
+ * |
+ * | * [branch_b)]
+ * |/ Add Class1 under Model1
+ * | Add Class2 under Model2
+ * |
+ * [branch_a]
+ * Initial commit
+ * - A project with 2 models, 2 diagrams
+ * </pre>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMER004() throws Exception {
+ Path projectPath = getRepositoryPath().resolve("MER004");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/automerging/MER004/branch_a/model.di")//
+ .addContentToCopy("data/automerging/MER004/branch_a/model.uml") //
+ .addContentToCopy("data/automerging/MER004/branch_a/model.notation") //
+ .addContentToCopy("data/automerging/MER004/branch_a/model2.di")//
+ .addContentToCopy("data/automerging/MER004/branch_a/model2.uml") //
+ .addContentToCopy("data/automerging/MER004/branch_a/model2.notation") //
+ .create(projectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit" + EOL + "- A project with 2 models, 2 diagrams");
+ createBranch(branchA, "master");
+
+ // Creates branch c
+ String branchC = "branch_c";
+ createBranchAndCheckout(branchC, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/automerging/MER004/branch_c/model.di")//
+ .addContentToCopy("data/automerging/MER004/branch_c/model.uml") //
+ .addContentToCopy("data/automerging/MER004/branch_c/model.notation") //
+ .addContentToCopy("data/automerging/MER004/branch_c/model2.di")//
+ .addContentToCopy("data/automerging/MER004/branch_c/model2.uml") //
+ .addContentToCopy("data/automerging/MER004/branch_c/model2.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Add Class3 under Model1" + EOL + "Add Class4 under Model2");
+
+ // Creates branch b
+ String branchB = "branch_b";
+ createBranchAndCheckout(branchB, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/automerging/MER004/branch_b/model.di")//
+ .addContentToCopy("data/automerging/MER004/branch_b/model.uml") //
+ .addContentToCopy("data/automerging/MER004/branch_b/model.notation") //
+ .addContentToCopy("data/automerging/MER004/branch_b/model2.di")//
+ .addContentToCopy("data/automerging/MER004/branch_b/model2.uml") //
+ .addContentToCopy("data/automerging/MER004/branch_b/model2.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Add Class1 under Model1" + EOL + "Add Class2 under Model2");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchC);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertOutputMessageEnd("Merge made by 'recursive' strategy." + EOL + EOL);
+ assertEquals(Returns.COMPLETE.code(), result);
+
+ final String class1URIFragment = "_adib0C9QEeShUolneTgohg";
+ final String class3URIFragment = "_lztC0C9QEeShUolneTgohg";
+ assertExistInResource(project.toPath().resolve("model.uml"), class1URIFragment, class3URIFragment);
+
+ final String class2URIFragment = "_a7N2UC9QEeShUolneTgohg";
+ final String class4URIFragment = "_m3mv0C9QEeShUolneTgohg";
+ assertExistInResource(project.toPath().resolve("model2.uml"), class2URIFragment, class4URIFragment);
+
+ final String class1ShapeURIFragment = "_adjp8C9QEeShUolneTgohg";
+ final String class3ShapeURIFragment = "_lzuQ8C9QEeShUolneTgohg";
+ assertExistInResource(project.toPath().resolve("model.notation"), class1ShapeURIFragment,
+ class3ShapeURIFragment);
+
+ final String class2ShapeURIFragment = "_a7PEcC9QEeShUolneTgohg";
+ final String class4ShapeURIFragment = "_m3nW4C9QEeShUolneTgohg";
+ assertExistInResource(project.toPath().resolve("model2.notation"), class2ShapeURIFragment,
+ class4ShapeURIFragment);
+
+ }
+
+ /**
+ * <pre>
+ * * [HEAD] [branch_c]
+ * | Delete Class1 and Class2
+ * |
+ * | * [branch_b]
+ * |/ Add attribute1 under Class1
+ * | Add attribute2 under Class2
+ * |
+ * [branch_a]
+ * Initial commit
+ * - 1 project with 2 models, 2 diagrams
+ * - add Class1 under Model1, Class2 under Model2
+ *
+ * </pre>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMER005() throws Exception {
+ Path projectPath = getRepositoryPath().resolve("MER005");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/conflicts/MER005/branch_a/model.di")//
+ .addContentToCopy("data/conflicts/MER005/branch_a/model.uml") //
+ .addContentToCopy("data/conflicts/MER005/branch_a/model.notation") //
+ .addContentToCopy("data/conflicts/MER005/branch_a/model2.di")//
+ .addContentToCopy("data/conflicts/MER005/branch_a/model2.uml") //
+ .addContentToCopy("data/conflicts/MER005/branch_a/model2.notation") //
+ .create(projectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit" + EOL + " - 1 project with 2 models, 2 diagrams" + EOL
+ + " - add Class1 under Model1, Class2 under Model2");
+ createBranch(branchA, "master");
+
+ // Creates branch c
+ String branchC = "branch_c";
+ createBranchAndCheckout(branchC, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER005/branch_c/model.di")//
+ .addContentToCopy("data/conflicts/MER005/branch_c/model.uml") //
+ .addContentToCopy("data/conflicts/MER005/branch_c/model.notation") //
+ .addContentToCopy("data/conflicts/MER005/branch_c/model2.di")//
+ .addContentToCopy("data/conflicts/MER005/branch_c/model2.uml") //
+ .addContentToCopy("data/conflicts/MER005/branch_c/model2.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Delete Class1 and Class2");
+
+ // Creates branch b
+ String branchB = "branch_b";
+ createBranchAndCheckout(branchB, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER005/branch_b/model.di")//
+ .addContentToCopy("data/conflicts/MER005/branch_b/model.uml") //
+ .addContentToCopy("data/conflicts/MER005/branch_b/model.notation") //
+ .addContentToCopy("data/conflicts/MER005/branch_b/model2.di")//
+ .addContentToCopy("data/conflicts/MER005/branch_b/model2.uml") //
+ .addContentToCopy("data/conflicts/MER005/branch_b/model2.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Add attribute1 under Class1" + EOL + "Add attribute2 under Class2");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchC);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertNoConflitMarker(projectPath.resolve("model.uml"), projectPath.resolve("model.notation"),
+ projectPath.resolve("model2.uml"), projectPath.resolve("model2.notation"));
+
+ assertEquals(Returns.ABORTED.code(), result);
+
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("Auto-merging failed in ").append("MER005/model.notation").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER005/model.uml").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER005/model2.notation").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER005/model2.uml").append(EOL);
+ expectedOut.append("Automatic merge failed; fix conflicts and then commit the result.").append(EOL)
+ .append(EOL);
+ assertOutputMessageEnd(expectedOut.toString());
+
+ Set<String> expectedConflictingFilePath = Sets.newHashSet("MER005/model.uml",
+ "MER005/model.notation", "MER005/model2.uml", "MER005/model2.notation");
+ assertEquals(expectedConflictingFilePath, getGit().status().call().getConflicting());
+
+ }
+
+ /**
+ * <h3>Test MER006</h3>
+ * <p>
+ * Successives conflicts on multiple models in multiple files (one file per model)
+ * </p>
+ *
+ * <pre>
+ * * [branch_d]
+ * | Delete Class2
+ * |
+ * [branch_c] Delete Class1
+ * |
+ * | * [branch_b]
+ * |/ Add attribute1 under Class1
+ * | Add attribute2 under Class2
+ * |
+ * [branch_a]
+ * Initial commit
+ * - 1 project with 2 models, 2 diagrams
+ * - add Class1 under Model1, Class2 under Model2
+ *
+ * </pre>
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMER006() throws Exception {
+ Path projectPath = getRepositoryPath().resolve("MER006");
+ File project = new ProjectBuilder(this) //
+ .addContentToCopy("data/conflicts/MER006/branch_a/model.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_a/model.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_a/model.notation") //
+ .addContentToCopy("data/conflicts/MER006/branch_a/model2.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_a/model2.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_a/model2.notation") //
+ .create(projectPath);
+ String branchA = "branch_a";
+ addAllAndCommit("Initial commit" + EOL + " - 1 project with 2 models, 2 diagrams" + EOL
+ + " - add Class1 under Model1, Class2 under Model2");
+ createBranch(branchA, "master");
+
+ // Creates branch c
+ String branchC = "branch_c";
+ createBranchAndCheckout(branchC, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER006/branch_c/model.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_c/model.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_c/model.notation") //
+ .addContentToCopy("data/conflicts/MER006/branch_c/model2.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_c/model2.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_c/model2.notation") //
+ .create(projectPath);
+
+ addAllAndCommit(" Delete Class1");
+
+ // Creates branch d
+ String branchD = "branch_d";
+ createBranchAndCheckout(branchD, branchC);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER006/branch_d/model.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_d/model.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_d/model.notation") //
+ .addContentToCopy("data/conflicts/MER006/branch_d/model2.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_d/model2.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_d/model2.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Delete Class2");
+
+ // Creates branch b
+ String branchB = "branch_b";
+ createBranchAndCheckout(branchB, branchA);
+
+ project = new ProjectBuilder(this) //
+ .clean(true) //
+ .addContentToCopy("data/conflicts/MER006/branch_b/model.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_b/model.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_b/model.notation") //
+ .addContentToCopy("data/conflicts/MER006/branch_b/model2.di")//
+ .addContentToCopy("data/conflicts/MER006/branch_b/model2.uml") //
+ .addContentToCopy("data/conflicts/MER006/branch_b/model2.notation") //
+ .create(projectPath);
+
+ addAllAndCommit("Add attribute1 under Class1, attribute2 under Class2");
+
+ getGit().close();
+
+ // Creates Oomph model
+ File userSetupFile = createPapyrusUserOomphModel(project);
+
+ // Mocks that the commands is lauched from the git repository folder.
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Sets args
+ getContext().addArg(getRepositoryPath().resolve(".git").toString(), userSetupFile.getAbsolutePath(),
+ branchD);
+
+ // Runs command
+ Object result = getApp().start(getContext());
+
+ // Uncomments to displays output
+ printOut();
+ printErr();
+
+ IProject[] projectInWorkspace = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ assertEquals(1, projectInWorkspace.length);
+
+ assertNoConflitMarker(projectPath.resolve("model.uml"), projectPath.resolve("model.notation"),
+ projectPath.resolve("model2.uml"), projectPath.resolve("model2.notation"));
+
+ assertEquals(Returns.ABORTED.code(), result);
+
+ StringBuilder expectedOut = new StringBuilder();
+ expectedOut.append("Auto-merging failed in ").append("MER006/model.notation").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER006/model.uml").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER006/model2.notation").append(EOL);
+ expectedOut.append("Auto-merging failed in ").append("MER006/model2.uml").append(EOL);
+ expectedOut.append("Automatic merge failed; fix conflicts and then commit the result.").append(EOL)
+ .append(EOL);
+ assertOutputMessageEnd(expectedOut.toString());
+
+ Set<String> expectedConflictingFilePath = Sets.newHashSet("MER006/model.uml",
+ "MER006/model.notation", "MER006/model2.uml", "MER006/model2.notation");
+ assertEquals(expectedConflictingFilePath, getGit().status().call().getConflicting());
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.notation
new file mode 100644
index 0000000..27d5144
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_L4ukIC3HEeSN_5D5iyrZGQ" type="PapyrusUMLClassDiagram" name="Diagram1" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_L4ukIS3HEeSN_5D5iyrZGQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_L4tWAC3HEeSN_5D5iyrZGQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.uml
new file mode 100644
index 0000000..7e56504
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_a/model.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_L4tWAC3HEeSN_5D5iyrZGQ" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.notation
new file mode 100644
index 0000000..fe79745
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_L4ukIC3HEeSN_5D5iyrZGQ" type="PapyrusUMLClassDiagram" name="Diagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_bB3tgC3HEeSN_5D5iyrZGQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_bB4UkC3HEeSN_5D5iyrZGQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_bB47oC3HEeSN_5D5iyrZGQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_bB47oS3HEeSN_5D5iyrZGQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_bB47oi3HEeSN_5D5iyrZGQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_bB47oy3HEeSN_5D5iyrZGQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_bB5isC3HEeSN_5D5iyrZGQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_bB5isS3HEeSN_5D5iyrZGQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_bB5isi3HEeSN_5D5iyrZGQ" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_bB5isy3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_bB5itC3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_bB5itS3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bB5iti3HEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_bB5ity3HEeSN_5D5iyrZGQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_bB5iuC3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_bB5iuS3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_bB5iui3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bB5iuy3HEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_bB5ivC3HEeSN_5D5iyrZGQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_bB5ivS3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_bB5ivi3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_bB5ivy3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bB5iwC3HEeSN_5D5iyrZGQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_bB2fYC3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bB3tgS3HEeSN_5D5iyrZGQ" x="62" y="76"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_L4ukIS3HEeSN_5D5iyrZGQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_L4tWAC3HEeSN_5D5iyrZGQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.uml
new file mode 100644
index 0000000..865a1bf
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_b/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_L4tWAC3HEeSN_5D5iyrZGQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_bB2fYC3HEeSN_5D5iyrZGQ" name="Class1"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.notation
new file mode 100644
index 0000000..fd855a8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_L4ukIC3HEeSN_5D5iyrZGQ" type="PapyrusUMLClassDiagram" name="Diagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_hfJS8C3HEeSN_5D5iyrZGQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_hfKhEC3HEeSN_5D5iyrZGQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_hfKhES3HEeSN_5D5iyrZGQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_hfLIIC3HEeSN_5D5iyrZGQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_hfLIIS3HEeSN_5D5iyrZGQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_hfLIIi3HEeSN_5D5iyrZGQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_hfLIIy3HEeSN_5D5iyrZGQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_hfLIJC3HEeSN_5D5iyrZGQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_hfLvMC3HEeSN_5D5iyrZGQ" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_hfLvMS3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_hfLvMi3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_hfLvMy3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_hfLvNC3HEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_hfLvNS3HEeSN_5D5iyrZGQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_hfLvNi3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_hfLvNy3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_hfLvOC3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_hfLvOS3HEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_hfLvOi3HEeSN_5D5iyrZGQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_hfLvOy3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_hfLvPC3HEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_hfLvPS3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_hfLvPi3HEeSN_5D5iyrZGQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_hfIr4C3HEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_hfJS8S3HEeSN_5D5iyrZGQ" x="305" y="43"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_L4ukIS3HEeSN_5D5iyrZGQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_L4tWAC3HEeSN_5D5iyrZGQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.uml
new file mode 100644
index 0000000..277c378
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER003/branch_c/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_L4tWAC3HEeSN_5D5iyrZGQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_hfIr4C3HEeSN_5D5iyrZGQ" name="Class2"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.notation
new file mode 100644
index 0000000..6dce3f6
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Ml4vgC9QEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_Ml4vgS9QEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_Ml4IcC9QEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.uml
new file mode 100644
index 0000000..b5c2b18
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Ml4IcC9QEeShUolneTgohg" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.notation
new file mode 100644
index 0000000..e024b69
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_PWOwMC9QEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_PWOwMS9QEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_PWNiEC9QEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.uml
new file mode 100644
index 0000000..5dd2c33
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_a/model2.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_PWNiEC9QEeShUolneTgohg" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.notation
new file mode 100644
index 0000000..d93037f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Ml4vgC9QEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_adjp8C9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_adkRAC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_adkRAS9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_adk4EC9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_adk4ES9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_adk4Ei9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_adk4Ey9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_adk4FC9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_adlfIC9QEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_adlfIS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_adlfIi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_adlfIy9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_adlfJC9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_adlfJS9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_adlfJi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_adlfJy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_adlfKC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_adlfKS9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_adlfKi9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_adlfKy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_adlfLC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_adlfLS9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_adlfLi9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_adib0C9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_adjp8S9QEeShUolneTgohg" x="35" y="56"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_Ml4vgS9QEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_Ml4IcC9QEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.uml
new file mode 100644
index 0000000..56ec489
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Ml4IcC9QEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_adib0C9QEeShUolneTgohg" name="Class1"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.notation
new file mode 100644
index 0000000..481e9e4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_PWOwMC9QEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_a7PEcC9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_a7PrgC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_a7PrgS9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_a7QSkC9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_a7QSkS9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_a7QSki9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_a7QSky9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_a7Q5oC9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_a7Q5oS9QEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_a7Q5oi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_a7Q5oy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_a7Q5pC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_a7Q5pS9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_a7Q5pi9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_a7Q5py9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_a7Q5qC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_a7Q5qS9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_a7Q5qi9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_a7Q5qy9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_a7Q5rC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_a7Q5rS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_a7Q5ri9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_a7Q5ry9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model2.uml#_a7N2UC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_a7PEcS9QEeShUolneTgohg" x="31" y="51"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_PWOwMS9QEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_PWNiEC9QEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.uml
new file mode 100644
index 0000000..5d50dda
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_b/model2.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_PWNiEC9QEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_a7N2UC9QEeShUolneTgohg" name="Class2"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.notation
new file mode 100644
index 0000000..d63cc63
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Ml4vgC9QEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_lzuQ8C9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_lzu4AC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_lzu4AS9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_lzvfEC9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_lzvfES9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_lzvfEi9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_lzvfEy9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_lzvfFC9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_lzwGIC9QEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_lzwGIS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_lzwGIi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_lzwGIy9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_lzwGJC9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_lzwGJS9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_lzwGJi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_lzwGJy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_lzwGKC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_lzwGKS9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_lzwGKi9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_lzwGKy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_lzwGLC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_lzwGLS9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_lzwGLi9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_lztC0C9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_lzuQ8S9QEeShUolneTgohg" x="285" y="39"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_Ml4vgS9QEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_Ml4IcC9QEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.uml
new file mode 100644
index 0000000..8ca5aa7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Ml4IcC9QEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_lztC0C9QEeShUolneTgohg" name="Class3"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.notation
new file mode 100644
index 0000000..4805ae0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_PWOwMC9QEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_m3nW4C9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_m3olAC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_m3olAS9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_m3olAi9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_m3olAy9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_m3pMEC9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_m3pMES9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_m3pMEi9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_m3pMEy9QEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_m3pMFC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m3pMFS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m3pMFi9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m3pMFy9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_m3pMGC9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_m3pMGS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m3pMGi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m3pMGy9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m3pMHC9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_m3pMHS9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_m3pMHi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_m3pMHy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_m3pMIC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m3pMIS9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model2.uml#_m3mv0C9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m3nW4S9QEeShUolneTgohg" x="278" y="39"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_PWOwMS9QEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_PWNiEC9QEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.uml
new file mode 100644
index 0000000..4aa0899
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/automerging/MER004/branch_c/model2.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_PWNiEC9QEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_m3mv0C9QEeShUolneTgohg" name="Class4"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.notation
new file mode 100644
index 0000000..a7cc34e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_vafGICz7EeSRuc4bHhOraQ" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_wBQLMCz7EeSRuc4bHhOraQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_wBRZUCz7EeSRuc4bHhOraQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_wBSAYCz7EeSRuc4bHhOraQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_wBSAYSz7EeSRuc4bHhOraQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_wBSAYiz7EeSRuc4bHhOraQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_wBSAYyz7EeSRuc4bHhOraQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_wBSncCz7EeSRuc4bHhOraQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_wBSncSz7EeSRuc4bHhOraQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_wBSnciz7EeSRuc4bHhOraQ" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_wBSncyz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_wBSndCz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_wBSndSz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBSndiz7EeSRuc4bHhOraQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_wBSndyz7EeSRuc4bHhOraQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_wBSneCz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_wBSneSz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_wBSneiz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBSneyz7EeSRuc4bHhOraQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_wBTOgCz7EeSRuc4bHhOraQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_wBTOgSz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_wBTOgiz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_wBTOgyz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBTOhCz7EeSRuc4bHhOraQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_wBO9ECz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBQLMSz7EeSRuc4bHhOraQ" x="35" y="40" width="137" height="159"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_vafGISz7EeSRuc4bHhOraQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_vad4ACz7EeSRuc4bHhOraQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.uml
new file mode 100644
index 0000000..c9090f1
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_a/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_vad4ACz7EeSRuc4bHhOraQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_wBO9ECz7EeSRuc4bHhOraQ" name="Class1"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.notation
new file mode 100644
index 0000000..df6a90e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.notation
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_vafGICz7EeSRuc4bHhOraQ" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_wBQLMCz7EeSRuc4bHhOraQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_wBRZUCz7EeSRuc4bHhOraQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_wBSAYCz7EeSRuc4bHhOraQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_wBSAYSz7EeSRuc4bHhOraQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_wBSAYiz7EeSRuc4bHhOraQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_wBSAYyz7EeSRuc4bHhOraQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_wBSncCz7EeSRuc4bHhOraQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_wBSncSz7EeSRuc4bHhOraQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_wBSnciz7EeSRuc4bHhOraQ" type="7017">
+ <children xmi:type="notation:Shape" xmi:id="_JDkZICz8EeSRuc4bHhOraQ" type="3012" fontName="Segoe UI" lineColor="0">
+ <element xmi:type="uml:Property" href="model.uml#_JDaBECz8EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_JDkZISz8EeSRuc4bHhOraQ"/>
+ </children>
+ <styles xmi:type="notation:TitleStyle" xmi:id="_wBSncyz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_wBSndCz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_wBSndSz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBSndiz7EeSRuc4bHhOraQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_wBSndyz7EeSRuc4bHhOraQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_wBSneCz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_wBSneSz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_wBSneiz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBSneyz7EeSRuc4bHhOraQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_wBTOgCz7EeSRuc4bHhOraQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_wBTOgSz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_wBTOgiz7EeSRuc4bHhOraQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_wBTOgyz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBTOhCz7EeSRuc4bHhOraQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_wBO9ECz7EeSRuc4bHhOraQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_wBQLMSz7EeSRuc4bHhOraQ" x="35" y="40" width="137" height="159"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_vafGISz7EeSRuc4bHhOraQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_vad4ACz7EeSRuc4bHhOraQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.uml
new file mode 100644
index 0000000..5ca0d23
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_b/model.uml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_vad4ACz7EeSRuc4bHhOraQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_wBO9ECz7EeSRuc4bHhOraQ" name="Class1">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_JDaBECz8EeSRuc4bHhOraQ" name="Attribute1"/>
+ </packagedElement>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.notation
new file mode 100644
index 0000000..2a99a4e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_vafGICz7EeSRuc4bHhOraQ" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_vafGISz7EeSRuc4bHhOraQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_vad4ACz7EeSRuc4bHhOraQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.uml
new file mode 100644
index 0000000..d306657
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER001/branch_c/model.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_vad4ACz7EeSRuc4bHhOraQ" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.notation
new file mode 100644
index 0000000..0fe3149
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.notation
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z4I6wC3GEeSN_5D5iyrZGQ" type="PapyrusUMLClassDiagram" name="Diagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_b45RkC3GEeSN_5D5iyrZGQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_b4_YMC3GEeSN_5D5iyrZGQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_b4_YMS3GEeSN_5D5iyrZGQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_b4__QC3GEeSN_5D5iyrZGQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_b4__QS3GEeSN_5D5iyrZGQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_b4__Qi3GEeSN_5D5iyrZGQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_b5AmUC3GEeSN_5D5iyrZGQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_b5B0cC3GEeSN_5D5iyrZGQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_b5DpoC3GEeSN_5D5iyrZGQ" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_b5DpoS3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_b5Dpoi3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_b5Dpoy3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b5DppC3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_b5DppS3GEeSN_5D5iyrZGQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_b5Dppi3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_b5Dppy3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_b5DpqC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b5DpqS3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_b5EQsC3GEeSN_5D5iyrZGQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_b5EQsS3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_b5EQsi3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_b5EQsy3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b5EQtC3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_b4iFMC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b45RkS3GEeSN_5D5iyrZGQ" x="51" y="46"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_etQPkC3GEeSN_5D5iyrZGQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etRdsC3GEeSN_5D5iyrZGQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSEwC3GEeSN_5D5iyrZGQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etSEwS3GEeSN_5D5iyrZGQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSEwi3GEeSN_5D5iyrZGQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etSEwy3GEeSN_5D5iyrZGQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSr0C3GEeSN_5D5iyrZGQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_etSr0S3GEeSN_5D5iyrZGQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etSr0i3GEeSN_5D5iyrZGQ" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etSr0y3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etSr1C3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etSr1S3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etSr1i3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etSr1y3GEeSN_5D5iyrZGQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etSr2C3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etSr2S3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etSr2i3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etSr2y3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etTS4C3GEeSN_5D5iyrZGQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etTS4S3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etTS4i3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etTS4y3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etTS5C3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_etOaYC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etQPkS3GEeSN_5D5iyrZGQ" x="181" y="46"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_Z4I6wS3GEeSN_5D5iyrZGQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_Z2-dIC3GEeSN_5D5iyrZGQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.uml
new file mode 100644
index 0000000..5e47b9a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_a/model.uml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z2-dIC3GEeSN_5D5iyrZGQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4iFMC3GEeSN_5D5iyrZGQ" name="Class1"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_etOaYC3GEeSN_5D5iyrZGQ" name="Class2"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.notation
new file mode 100644
index 0000000..6e1c93c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.notation
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z4I6wC3GEeSN_5D5iyrZGQ" type="PapyrusUMLClassDiagram" name="Diagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_b45RkC3GEeSN_5D5iyrZGQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_b4_YMC3GEeSN_5D5iyrZGQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_b4_YMS3GEeSN_5D5iyrZGQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_b4__QC3GEeSN_5D5iyrZGQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_b4__QS3GEeSN_5D5iyrZGQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_b4__Qi3GEeSN_5D5iyrZGQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_b5AmUC3GEeSN_5D5iyrZGQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_b5B0cC3GEeSN_5D5iyrZGQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_b5DpoC3GEeSN_5D5iyrZGQ" type="7017">
+ <children xmi:type="notation:Shape" xmi:id="_v0NJcC3GEeSN_5D5iyrZGQ" type="3012" fontName="Segoe UI" lineColor="0">
+ <element xmi:type="uml:Property" href="model.uml#_v0FNoC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_v0NJcS3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <styles xmi:type="notation:TitleStyle" xmi:id="_b5DpoS3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_b5Dpoi3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_b5Dpoy3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b5DppC3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_b5DppS3GEeSN_5D5iyrZGQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_b5Dppi3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_b5Dppy3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_b5DpqC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b5DpqS3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_b5EQsC3GEeSN_5D5iyrZGQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_b5EQsS3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_b5EQsi3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_b5EQsy3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b5EQtC3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_b4iFMC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_b45RkS3GEeSN_5D5iyrZGQ" x="51" y="46"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_etQPkC3GEeSN_5D5iyrZGQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etRdsC3GEeSN_5D5iyrZGQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSEwC3GEeSN_5D5iyrZGQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etSEwS3GEeSN_5D5iyrZGQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSEwi3GEeSN_5D5iyrZGQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etSEwy3GEeSN_5D5iyrZGQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSr0C3GEeSN_5D5iyrZGQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_etSr0S3GEeSN_5D5iyrZGQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etSr0i3GEeSN_5D5iyrZGQ" type="7017">
+ <children xmi:type="notation:Shape" xmi:id="_wqnNAC3GEeSN_5D5iyrZGQ" type="3012" fontName="Segoe UI" lineColor="0">
+ <element xmi:type="uml:Property" href="model.uml#_wql-4C3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_wqnNAS3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etSr0y3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etSr1C3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etSr1S3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etSr1i3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etSr1y3GEeSN_5D5iyrZGQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etSr2C3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etSr2S3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etSr2i3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etSr2y3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etTS4C3GEeSN_5D5iyrZGQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etTS4S3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etTS4i3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etTS4y3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etTS5C3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_etOaYC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etQPkS3GEeSN_5D5iyrZGQ" x="276" y="46"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_Z4I6wS3GEeSN_5D5iyrZGQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_Z2-dIC3GEeSN_5D5iyrZGQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.uml
new file mode 100644
index 0000000..21c1018
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_b/model.uml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z2-dIC3GEeSN_5D5iyrZGQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4iFMC3GEeSN_5D5iyrZGQ" name="Class1">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_v0FNoC3GEeSN_5D5iyrZGQ" name="Attribute1"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Class" xmi:id="_etOaYC3GEeSN_5D5iyrZGQ" name="Class2">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_wql-4C3GEeSN_5D5iyrZGQ" name="Attribute2"/>
+ </packagedElement>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.notation
new file mode 100644
index 0000000..4b80e85
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z4I6wC3GEeSN_5D5iyrZGQ" type="PapyrusUMLClassDiagram" name="Diagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_etQPkC3GEeSN_5D5iyrZGQ" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etRdsC3GEeSN_5D5iyrZGQ" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSEwC3GEeSN_5D5iyrZGQ" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etSEwS3GEeSN_5D5iyrZGQ" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSEwi3GEeSN_5D5iyrZGQ" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_etSEwy3GEeSN_5D5iyrZGQ" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_etSr0C3GEeSN_5D5iyrZGQ" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_etSr0S3GEeSN_5D5iyrZGQ" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etSr0i3GEeSN_5D5iyrZGQ" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etSr0y3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etSr1C3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etSr1S3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etSr1i3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etSr1y3GEeSN_5D5iyrZGQ" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etSr2C3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etSr2S3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etSr2i3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etSr2y3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_etTS4C3GEeSN_5D5iyrZGQ" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_etTS4S3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_etTS4i3GEeSN_5D5iyrZGQ"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_etTS4y3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etTS5C3GEeSN_5D5iyrZGQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_etOaYC3GEeSN_5D5iyrZGQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_etQPkS3GEeSN_5D5iyrZGQ" x="181" y="46"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_Z4I6wS3GEeSN_5D5iyrZGQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_Z2-dIC3GEeSN_5D5iyrZGQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.uml
new file mode 100644
index 0000000..369154f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_c/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z2-dIC3GEeSN_5D5iyrZGQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_etOaYC3GEeSN_5D5iyrZGQ" name="Class2"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.notation
new file mode 100644
index 0000000..fc05f50
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z4I6wC3GEeSN_5D5iyrZGQ" type="PapyrusUMLClassDiagram" name="Diagram1" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_Z4I6wS3GEeSN_5D5iyrZGQ"/>
+ <element xmi:type="uml:Model" href="model.uml#_Z2-dIC3GEeSN_5D5iyrZGQ"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.uml
new file mode 100644
index 0000000..a024182
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER002/branch_d/model.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_Z2-dIC3GEeSN_5D5iyrZGQ" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.notation
new file mode 100644
index 0000000..ac9d3ee
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rUK3MC9PEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_upXb8C9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_upYDAC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_upYqEC9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_upYqES9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_upYqEi9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_upYqEy9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_upYqFC9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_upYqFS9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_upYqFi9QEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_upZRIC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_upZRIS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_upZRIi9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upZRIy9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_upZRJC9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_upZRJS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_upZRJi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_upZRJy9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upZRKC9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_upZRKS9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_upZRKi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_upZRKy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_upZRLC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upZRLS9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_upWN0C9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upXb8S9QEeShUolneTgohg" x="37" y="43" width="162" height="155"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_rUK3MS9PEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_rUJpEC9PEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.uml
new file mode 100644
index 0000000..7b8aee8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rUJpEC9PEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_upWN0C9QEeShUolneTgohg" name="Class1"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.notation
new file mode 100644
index 0000000..2d43e47
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_uW5BUC9PEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_vRkEYC9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_vRlSgC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_vRlSgS9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_vRlSgi9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_vRlSgy9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_vRl5kC9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_vRl5kS9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_vRl5ki9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_vRl5ky9QEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_vRl5lC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_vRl5lS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_vRl5li9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRl5ly9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_vRl5mC9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_vRl5mS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_vRl5mi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_vRl5my9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRl5nC9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_vRmgoC9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_vRmgoS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_vRmgoi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_vRmgoy9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRmgpC9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model2.uml#_vRjdUC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRkEYS9QEeShUolneTgohg" x="85" y="59" width="177" height="156"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_uW5BUS9PEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_uW3zMC9PEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.uml
new file mode 100644
index 0000000..6cbeb9c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_a/model2.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_uW3zMC9PEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_vRjdUC9QEeShUolneTgohg" name="Class2"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.notation
new file mode 100644
index 0000000..2e87e79
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.notation
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rUK3MC9PEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_upXb8C9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_upYDAC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_upYqEC9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_upYqES9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_upYqEi9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_upYqEy9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_upYqFC9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_upYqFS9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_upYqFi9QEeShUolneTgohg" type="7017">
+ <children xmi:type="notation:Shape" xmi:id="_7YQwcC9QEeShUolneTgohg" type="3012" fontName="Segoe UI" lineColor="0">
+ <element xmi:type="uml:Property" href="model.uml#_7YPiUC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_7YQwcS9QEeShUolneTgohg"/>
+ </children>
+ <styles xmi:type="notation:TitleStyle" xmi:id="_upZRIC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_upZRIS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_upZRIi9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upZRIy9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_upZRJC9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_upZRJS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_upZRJi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_upZRJy9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upZRKC9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_upZRKS9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_upZRKi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_upZRKy9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_upZRLC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upZRLS9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_upWN0C9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_upXb8S9QEeShUolneTgohg" x="37" y="43" width="162" height="155"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_rUK3MS9PEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_rUJpEC9PEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.uml
new file mode 100644
index 0000000..fd1b1c9
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model.uml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rUJpEC9PEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_upWN0C9QEeShUolneTgohg" name="Class1">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_7YPiUC9QEeShUolneTgohg" name="Attribute1"/>
+ </packagedElement>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.notation
new file mode 100644
index 0000000..a17c58d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.notation
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_uW5BUC9PEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_vRkEYC9QEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_vRlSgC9QEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_vRlSgS9QEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_vRlSgi9QEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_vRlSgy9QEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_vRl5kC9QEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_vRl5kS9QEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_vRl5ki9QEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_vRl5ky9QEeShUolneTgohg" type="7017">
+ <children xmi:type="notation:Shape" xmi:id="_8tZ-cC9QEeShUolneTgohg" type="3012" fontName="Segoe UI" lineColor="0">
+ <element xmi:type="uml:Property" href="model2.uml#_8tYwUC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_8tZ-cS9QEeShUolneTgohg"/>
+ </children>
+ <styles xmi:type="notation:TitleStyle" xmi:id="_vRl5lC9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_vRl5lS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_vRl5li9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRl5ly9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_vRl5mC9QEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_vRl5mS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_vRl5mi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_vRl5my9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRl5nC9QEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_vRmgoC9QEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_vRmgoS9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_vRmgoi9QEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_vRmgoy9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRmgpC9QEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model2.uml#_vRjdUC9QEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_vRkEYS9QEeShUolneTgohg" x="85" y="59" width="177" height="156"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_uW5BUS9PEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_uW3zMC9PEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.uml
new file mode 100644
index 0000000..63c0ecc
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_b/model2.uml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_uW3zMC9PEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_vRjdUC9QEeShUolneTgohg" name="Class2">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_8tYwUC9QEeShUolneTgohg" name="Attribute2"/>
+ </packagedElement>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.notation
new file mode 100644
index 0000000..227bb67
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rUK3MC9PEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_rUK3MS9PEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_rUJpEC9PEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.uml
new file mode 100644
index 0000000..9554cf0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rUJpEC9PEeShUolneTgohg" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.notation
new file mode 100644
index 0000000..afa1c99
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_uW5BUC9PEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_uW5BUS9PEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_uW3zMC9PEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.uml
new file mode 100644
index 0000000..54a5581
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER005/branch_c/model2.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_uW3zMC9PEeShUolneTgohg" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.notation
new file mode 100644
index 0000000..ff9e08a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5o9QC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_45yQ8C9SEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_45zfEC9SEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_45zfES9SEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_45zfEi9SEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_45zfEy9SEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_45zfFC9SEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_45zfFS9SEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_450GIC9SEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_450GIS9SEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_450GIi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_450GIy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_450GJC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_450GJS9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_450GJi9SEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_450GJy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_450GKC9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_450GKS9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_450GKi9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_450GKy9SEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_450GLC9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_450GLS9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_450GLi9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_450GLy9SEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_45xC0C9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_45yQ8S9SEeShUolneTgohg" x="64" y="40" width="177" height="182"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_t5o9QS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_t5oWMC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.uml
new file mode 100644
index 0000000..d43e7c3
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5oWMC9SEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_45xC0C9SEeShUolneTgohg" name="Class1"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.notation
new file mode 100644
index 0000000..69bd08c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LK3cC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_6AgocC9SEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6AhPgC9SEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6AhPgS9SEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6Ah2kC9SEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6Ah2kS9SEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6Ah2ki9SEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6Ah2ky9SEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6Ah2lC9SEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6AidoC9SEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6AidoS9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6Aidoi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6Aidoy9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AidpC9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6AidpS9SEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6Aidpi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6Aidpy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6AidqC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AidqS9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6Aidqi9SEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6Aidqy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6AidrC9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6AidrS9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6Aidri9SEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model2.uml#_6AfaUC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AgocS9SEeShUolneTgohg" x="47" y="46" width="199" height="185"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_4LK3cS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_4LKQYC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.uml
new file mode 100644
index 0000000..decf638
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_a/model2.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LKQYC9SEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_6AfaUC9SEeShUolneTgohg" name="Class2"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.notation
new file mode 100644
index 0000000..1713e8c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.notation
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5o9QC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_45yQ8C9SEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_45zfEC9SEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_45zfES9SEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_45zfEi9SEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_45zfEy9SEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_45zfFC9SEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_45zfFS9SEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_450GIC9SEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_450GIS9SEeShUolneTgohg" type="7017">
+ <children xmi:type="notation:Shape" xmi:id="_COCDgC9TEeShUolneTgohg" type="3012" fontName="Segoe UI" lineColor="0">
+ <element xmi:type="uml:Property" href="model.uml#_COA1YC9TEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_COCDgS9TEeShUolneTgohg"/>
+ </children>
+ <styles xmi:type="notation:TitleStyle" xmi:id="_450GIi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_450GIy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_450GJC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_450GJS9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_450GJi9SEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_450GJy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_450GKC9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_450GKS9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_450GKi9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_450GKy9SEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_450GLC9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_450GLS9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_450GLi9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_450GLy9SEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model.uml#_45xC0C9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_45yQ8S9SEeShUolneTgohg" x="64" y="40" width="177" height="182"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_t5o9QS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_t5oWMC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.uml
new file mode 100644
index 0000000..1bf536c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model.uml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5oWMC9SEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_45xC0C9SEeShUolneTgohg" name="Class1">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_COA1YC9TEeShUolneTgohg" name="Attribute1"/>
+ </packagedElement>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.notation
new file mode 100644
index 0000000..7fc47e4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.notation
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LK3cC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_6AgocC9SEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6AhPgC9SEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6AhPgS9SEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6Ah2kC9SEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6Ah2kS9SEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6Ah2ki9SEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6Ah2ky9SEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6Ah2lC9SEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6AidoC9SEeShUolneTgohg" type="7017">
+ <children xmi:type="notation:Shape" xmi:id="_DnslIC9TEeShUolneTgohg" type="3012" fontName="Segoe UI" lineColor="0">
+ <element xmi:type="uml:Property" href="model2.uml#_DnqI4C9TEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_DnslIS9TEeShUolneTgohg"/>
+ </children>
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6AidoS9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6Aidoi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6Aidoy9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AidpC9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6AidpS9SEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6Aidpi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6Aidpy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6AidqC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AidqS9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6Aidqi9SEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6Aidqy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6AidrC9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6AidrS9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6Aidri9SEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model2.uml#_6AfaUC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AgocS9SEeShUolneTgohg" x="47" y="46" width="199" height="185"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_4LK3cS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_4LKQYC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.uml
new file mode 100644
index 0000000..040bc97
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_b/model2.uml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LKQYC9SEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_6AfaUC9SEeShUolneTgohg" name="Class2">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_DnqI4C9TEeShUolneTgohg" name="Attribute2"/>
+ </packagedElement>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.notation
new file mode 100644
index 0000000..a5d6c69
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5o9QC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_t5o9QS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_t5oWMC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.uml
new file mode 100644
index 0000000..e0a709b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5oWMC9SEeShUolneTgohg" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.notation
new file mode 100644
index 0000000..69bd08c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.notation
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LK3cC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_6AgocC9SEeShUolneTgohg" type="2008" fontName="Segoe UI" lineColor="0">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6AhPgC9SEeShUolneTgohg" source="ShadowFigure">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6AhPgS9SEeShUolneTgohg" key="ShadowFigure_Value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6Ah2kC9SEeShUolneTgohg" source="displayNameLabelIcon">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6Ah2kS9SEeShUolneTgohg" key="displayNameLabelIcon_value" value="false"/>
+ </eAnnotations>
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_6Ah2ki9SEeShUolneTgohg" source="QualifiedName">
+ <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_6Ah2ky9SEeShUolneTgohg" key="QualifiedNameDepth" value="1000"/>
+ </eAnnotations>
+ <children xmi:type="notation:DecorationNode" xmi:id="_6Ah2lC9SEeShUolneTgohg" type="5029"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6AidoC9SEeShUolneTgohg" type="7017">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6AidoS9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6Aidoi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6Aidoy9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AidpC9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6AidpS9SEeShUolneTgohg" type="7018">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6Aidpi9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6Aidpy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6AidqC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AidqS9SEeShUolneTgohg"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_6Aidqi9SEeShUolneTgohg" type="7019">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_6Aidqy9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:SortingStyle" xmi:id="_6AidrC9SEeShUolneTgohg"/>
+ <styles xmi:type="notation:FilteringStyle" xmi:id="_6AidrS9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6Aidri9SEeShUolneTgohg"/>
+ </children>
+ <element xmi:type="uml:Class" href="model2.uml#_6AfaUC9SEeShUolneTgohg"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6AgocS9SEeShUolneTgohg" x="47" y="46" width="199" height="185"/>
+ </children>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_4LK3cS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_4LKQYC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.uml
new file mode 100644
index 0000000..decf638
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_c/model2.uml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LKQYC9SEeShUolneTgohg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_6AfaUC9SEeShUolneTgohg" name="Class2"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.notation
new file mode 100644
index 0000000..a5d6c69
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5o9QC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram1" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_t5o9QS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model.uml#_t5oWMC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.uml
new file mode 100644
index 0000000..e0a709b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_t5oWMC9SEeShUolneTgohg" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.di b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.di
new file mode 100644
index 0000000..bf9abab
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.notation b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.notation
new file mode 100644
index 0000000..486777b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.notation
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LK3cC9SEeShUolneTgohg" type="PapyrusUMLClassDiagram" name="ClassDiagram2" measurementUnit="Pixel">
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_4LK3cS9SEeShUolneTgohg"/>
+ <element xmi:type="uml:Model" href="model2.uml#_4LKQYC9SEeShUolneTgohg"/>
+</notation:Diagram>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.uml b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.uml
new file mode 100644
index 0000000..058876c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/app/data/conflicts/MER006/branch_d/model2.uml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_4LKQYC9SEeShUolneTgohg" name="model"/>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/AbstractLogicalCommandTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/AbstractLogicalCommandTest.java
new file mode 100644
index 0000000..670f8fe
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/AbstractLogicalCommandTest.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import org.eclipse.emf.compare.git.pgm.AbstractLogicalAppTest;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.Test;
+
+/**
+ * Abstract class for logical command tests.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public abstract class AbstractLogicalCommandTest extends AbstractLogicalAppTest {
+
+ /**
+ * @return the name of the command under test.
+ */
+ protected abstract String getCommandName();
+
+ /**
+ * @return the expected usage message.
+ */
+ protected abstract String getExpectedUsage();
+
+ @Test
+ public void helpLogicalCommandTest() throws Exception {
+ // Asks command help
+ getContext().addArg(getCommandName(), "--help");
+ Object result = getApp().start(getContext());
+ assertOutput(getExpectedUsage());
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ }
+
+ @Test
+ public void incorrectSetupFileTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+ // Gives an incorrect path for the setup file
+ String incorrectSetupFilePath = getTestTmpFolder().resolve("wrongfile.setup").toString();
+ getContext().addArg(getCommandName(), incorrectSetupFilePath, "master");
+ Object result = getApp().start(getContext());
+ String expectedOut = "fatal: " + incorrectSetupFilePath + " setup file does not exist" + EOL;
+ assertOutput(expectedOut);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void missingSetupFileTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+ // Does not give a setup file
+ String missingSetupFilePath = getRepositoryPath().resolve("master").toString();
+ getContext().addArg(getCommandName(), "master");
+ Object result = getApp().start(getContext());
+ String expectedOut = "fatal: " + missingSetupFilePath + " setup file does not exist" + EOL; //
+ assertOutput(expectedOut);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void useOfGitDir() throws Exception {
+ // Sets context to be sure were are not in a git repository
+ setCmdLocation(getTestTmpFolder().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Provides the repository using the --git-dir parameter
+ // Use the --help option to avoid crashing the application and being able to test its parameters
+ String gitDirPath = getRepositoryPath().resolve(".git").toString();
+ getContext().addArg(getCommandName(), "--git-dir", gitDirPath, newSetupFile.getAbsolutePath(),
+ "--help");
+
+ Object result = getApp().start(getContext());
+ Repository repo = getLogicalCommand().getRepository();
+ assertNotNull(repo);
+ assertEquals(gitDirPath, repo.getDirectory().getAbsolutePath());
+ assertEquals(Returns.COMPLETE.code(), result);
+ }
+
+ @Test
+ public void useOfShowStackTrace() throws Exception {
+ // Sets context to be sure were are not in a git repository
+ setCmdLocation(getRepositoryPath().toString());
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Set the show stack trace option
+ // Use the --help option to avoid crashing the application and being able to test its parameters
+ getContext().addArg(getCommandName(), "--show-stack-trace", newSetupFile.getAbsolutePath(), "--help");
+
+ Object result = getApp().start(getContext());
+ assertTrue(getLogicalCommand().isShowStackTrace());
+ assertEquals(Returns.COMPLETE.code(), result);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffArgumentsTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffArgumentsTest.java
new file mode 100644
index 0000000..8c6004f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffArgumentsTest.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.junit.Test;
+
+/**
+ * Test of {@link LogicalDiffCommand}.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalDiffArgumentsTest extends AbstractLogicalCommandTest {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommandTest#getCommandName()
+ */
+ @Override
+ protected String getCommandName() {
+ return LogicalDiffCommand.LOGICAL_DIFF_CMD_NAME;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommandTest#getExpectedUsage()
+ */
+ @Override
+ protected String getExpectedUsage() {
+ //@formatter:off
+ return EOL
+ + "logicaldiff <setup> <commit> [<compareWithCommit>] [-- <path...>] [--git-dir gitFolderPath] [--help (-h)] [--show-stack-trace]" + EOL
+ + EOL
+ + " <setup> : Path to the setup file. The setup file is a Oomph" + EOL
+ + " model." + EOL
+ + " <commit> : Commit ID or branch name." + EOL
+ + " <compareWithCommit> : Commit ID or branch name. This is to view the" + EOL
+ + " changes between <commit> and <compareWithCommit> or" + EOL
+ + " HEAD if not specified." + EOL
+ + " -- <path...> : This is used to limit the diff to the named paths" + EOL
+ + " (you can give directory names and get diff for all" + EOL
+ + " files under them)." + EOL
+ + " --git-dir gitFolderPath : Path to the .git folder of your repository." + EOL
+ + " --help (-h) : Dispays help for this command." + EOL
+ + " --show-stack-trace : Use this option to display java stack trace in" + EOL
+ + " console on error." + EOL
+ + EOL ;
+ //@formatter:on
+ }
+
+ @Test
+ public void emptyRepoTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ File userSetupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Tests the command on an empty repo (not commit, no branch)
+ getContext().addArg(getCommandName(), userSetupFile.getAbsolutePath(), "master");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: master - not a valid git reference." + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void noCommitIDTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ File userSetupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // No reference
+ getContext().addArg(getCommandName(), userSetupFile.getAbsolutePath());
+ Object result = getApp().start(getContext());
+ String expectedMessage = "fatal: Argument \"<commit>\" is required in:" + EOL //
+ + getExpectedUsage() + EOL;
+ assertOutput(expectedMessage);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void incorrectIDTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ File setupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Gives an incorrect ref
+ getContext().addArg(getCommandName(), setupFile.getAbsolutePath(), "incorrectId");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: incorrectId - not a valid git reference." + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void incorrectCompareWithCommitIDTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ File setupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Gives an incorrect ref
+ getContext().addArg(getCommandName(), setupFile.getAbsolutePath(), "master", "incorrectId");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: incorrectId - not a valid git reference." + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void tooManyArgsTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ File setupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Tests referencing a commit using the name of a branch
+ getContext().addArg(getCommandName(), setupFile.getAbsolutePath(), "master", "master", "extraArg");
+ Object result = getApp().start(getContext());
+ String expectedOut = "fatal: Too many arguments: extraArg in:" + EOL//
+ + getExpectedUsage() //
+ + EOL; //
+ assertOutput(expectedOut);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void isNotAGitRepoTest() throws Exception {
+ Path myTmpDir = Files.createTempDirectory(getTestTmpFolder(), "NotARepo", new FileAttribute<?>[] {});
+ // Launches command from directory that is not contained by a git repository
+ setCmdLocation(myTmpDir.toString());
+
+ File setupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ getContext().addArg(getCommandName(), setupFile.getAbsolutePath(), "master");
+
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: Can't find git repository" + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ // TODO
+ // @Test
+ // public void correctPathTest() throws Exception {
+ // setCmdLocation(repositoryPath.toString());
+ // File newSetupFile = createOomphModel("setup.setup");
+ // CommittedFile aFile = createAndCommitAFile("aFile.txt", "Some content", "First contribution");
+ // CommittedFile newFile = createAndCommitAFile("test.txt", "Some content", "New commit");
+ // // Tests referencing a commit using the name of a branch
+ // context.addArg(getCommandName(), newSetupFile.getAbsolutePath(), "master", "--", aFile.getFile()
+ // .getAbsolutePath(), newFile.getFile().getAbsolutePath());
+ // Object result = getApp().start(context);
+ // assertOutputs("", "");
+ // assertEquals(Returns.COMPLETE, result);
+ // assertTrue(getLogicalCommand() instanceof LogicalDiffCommand);
+ // LogicalDiffCommand diffCmd = (LogicalDiffCommand)getLogicalCommand();
+ // assertNotNull(diffCmd.getPathFilter());
+ // assertNotNull(diffCmd.getCommit());
+ // assertNull(diffCmd.getOptionalCommit());
+ // }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffIntegrationTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffIntegrationTest.java
new file mode 100644
index 0000000..7b3faf7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffIntegrationTest.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.git.pgm.AbstractLogicalAppTest;
+import org.eclipse.emf.compare.git.pgm.LogicalApp;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.suite.AllIntegrationTests;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.eclipse.equinox.app.IApplication;
+import org.junit.Test;
+
+/**
+ * Should only be called from the tycho build since it used the emfcompare-git-pgm update to create the
+ * provided platform.
+ * <p>
+ * If you need to run it locally please set the system variable "emfcompare-git-pgm--updasite" to the location
+ * of update holding emfcompare-git-pgm plugins.
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalDiffIntegrationTest extends AbstractLogicalAppTest {
+
+ @Override
+ protected IApplication buildApp() {
+ return new LogicalApp(URI.createURI(
+ "platform:/fragment/org.eclipse.emf.compare.git.pgm.tests/model/lunaIntegrationTest.setup",
+ false));
+ }
+
+ @Test
+ public void nothingToDo() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(AllIntegrationTests.getProvidedPlatformLocation().toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // No reference
+ getContext().addArg(LogicalDiffCommand.LOGICAL_DIFF_CMD_NAME, newSetupFile.getAbsolutePath(),
+ "master", "master");
+ Object result = getApp().start(getContext());
+
+ printOut();
+ printErr();
+
+ assertOutputMessageEnd("No difference to display." + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommandArgumentsTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommandArgumentsTest.java
new file mode 100644
index 0000000..2f73bdb
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommandArgumentsTest.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeCommand.LOGICAL_MERGE_CMD_NAME;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.junit.Test;
+
+/**
+ * Test of {@link LogicalMergeCommand}.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalMergeCommandArgumentsTest extends AbstractLogicalCommandTest {
+
+ @Override
+ protected String getCommandName() {
+ return LOGICAL_MERGE_CMD_NAME;
+ }
+
+ @Override
+ protected String getExpectedUsage() {
+ //@formatter:off
+ return EOL //
+ + "logicalmerge <setup> <commit> [--debug (-d)] [--git-dir gitFolderPath] [--help (-h)] [--show-stack-trace] [-m message]" + EOL
+ + EOL
+ + " <setup> : Path to the setup file. The setup file is a Oomph" + EOL
+ + " model." +EOL
+ + " <commit> : Commit ID or branch name to merge." + EOL
+ + " --debug (-d) : Launched the provisonned eclipse in debug mode."+ EOL
+ + " --git-dir gitFolderPath : Path to the .git folder of your repository."+ EOL
+ + " --help (-h) : Dispays help for this command." + EOL
+ + " --show-stack-trace : Use this option to display java stack trace in" + EOL
+ + " console on error." + EOL
+ + " -m message : Set the commit message to be used for the merge" + EOL
+ + " commit (in case one is created)." + EOL
+ + EOL;
+ //@formatter:on
+ }
+
+ @Test
+ public void isNotAGitRepoTest() throws Exception {
+ Path myTmpDir = Files.createTempDirectory(getTestTmpFolder(), "NotARepo", new FileAttribute<?>[] {});
+ // Launches command from directory that is not contained by a git repository
+ setCmdLocation(myTmpDir.toString());
+
+ File setupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ getContext().addArg(getCommandName(), setupFile.getAbsolutePath(), "master");
+
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: Can't find git repository" + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void emptyRepoTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Creates a Oomph setup file
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File setupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Tests commant on an empty repo (not commit, no branch)
+ getContext().addArg(getCommandName(), setupFile.getAbsolutePath(), "master");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: master - not a valid git reference." + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void corruptSetupModelTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Creates some content for the first commit.
+ File project = new ProjectBuilder(this) //
+ .addNewFileContent("aFile.txt", "Some content") //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ Path corruptedSetupFilePath = project.toPath().resolve("aFile.txt");
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, corruptedSetupFilePath.toString(), "master");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: " + corruptedSetupFilePath.toString() + " is not a valid setup file" + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void validRepoTestIncorrectGitDirArg() throws Exception {
+ // Sets context to be sure were are not in a git repository
+ setCmdLocation(getTestTmpFolder().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Provides the repository using parameter
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, "--git-dir", "x/x/x/incorrectPathToGitDir",
+ newSetupFile.getAbsolutePath(), "master");
+
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: Can't find git repository" + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void validRepoNoCommitIDTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // No reference
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, newSetupFile.getAbsolutePath());
+ Object result = getApp().start(getContext());
+ //@formatter:off
+ String expectedMessage = "fatal: Argument \"<commit>\" is required in:" + EOL
+ + getExpectedUsage()
+ + EOL;
+ //@formatter:on
+ assertOutput(expectedMessage);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void validRepoIncorrectIDTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ // Gives an incorrect ref
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, newSetupFile.getAbsolutePath(), "incorrectId");
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: incorrectId - not a valid git reference." + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void tooManyArgsTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Tests referencing a commit using the name of a branch
+ getContext().addArg(getCommandName(), newSetupFile.getAbsolutePath(), "master", "extraArg");
+ Object result = getApp().start(getContext());
+ String expectedOut = "fatal: Too many arguments: extraArg in:" + EOL//
+ + getExpectedUsage() //
+ + EOL; //
+ assertOutput(expectedOut);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void incorrectMessageTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+ addAllAndCommit("First commit");
+
+ // Tests referencing a commit using the name of a branch
+ getContext().addArg(getCommandName(), newSetupFile.getAbsolutePath(), "master", "-m");
+ getApp().start(getContext());
+ assertTrue(getLogicalCommand() instanceof LogicalMergeCommand);
+ LogicalMergeCommand mergeCmd = (LogicalMergeCommand)getLogicalCommand();
+ assertNotNull(mergeCmd.getCommit());
+ String extectedOutput = "fatal: Option \"-m\" takes an operand in:" + EOL + getExpectedUsage() + EOL;
+ assertOutput(extectedOutput);
+ assertEmptyErrorMessage();
+ }
+
+ @Test
+ public void messageTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder().setInstallationTaskLocation(
+ oomphFolderPath.toString()).setWorkspaceLocation(oomphFolderPath.resolve("ws").toString())
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+ addAllAndCommit("First commit");
+
+ // Tests referencing a commit using the name of a branch
+ getContext().addArg(getCommandName(), newSetupFile.getAbsolutePath(), "master", "-m", "My message",
+ "--help");
+ getApp().start(getContext());
+ assertTrue(getLogicalCommand() instanceof LogicalMergeCommand);
+ LogicalMergeCommand mergeCmd = (LogicalMergeCommand)getLogicalCommand();
+ assertNotNull(mergeCmd.getCommit());
+ assertEquals("My message", ((LogicalMergeCommand)getLogicalCommand()).getMessage());
+
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommandIntegrationTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommandIntegrationTest.java
new file mode 100644
index 0000000..d2c710c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommandIntegrationTest.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeCommand.LOGICAL_MERGE_CMD_NAME;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.git.pgm.AbstractLogicalAppTest;
+import org.eclipse.emf.compare.git.pgm.LogicalApp;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.Options;
+import org.eclipse.emf.compare.git.pgm.suite.AllIntegrationTests;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.Test;
+
+/**
+ * Should only be called from the tycho build since it used the emfcompare-git-pgm update to create the
+ * provided platform.
+ * <p>
+ * If you need to run it locally please set the system variable "emfcompare-git-pgm--updasite" to the location
+ * of update holding emfcompare-git-pgm plugins.
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalMergeCommandIntegrationTest extends AbstractLogicalAppTest {
+
+ @Override
+ protected IApplication buildApp() {
+ return new LogicalApp(URI.createURI(
+ "platform:/fragment/org.eclipse.emf.compare.git.pgm.tests/model/lunaIntegrationTest.setup",
+ false));
+ }
+
+ @Test
+ public void alreadyUpToDateTest() throws Exception {
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(AllIntegrationTests.getProvidedPlatformLocation().toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+ addAllAndCommit("First commit");
+
+ // Tests referencing a commit using the name of a branch
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, newSetupFile.getAbsolutePath(), "master");
+ Object result = getApp().start(getContext());
+
+ printOut();
+ printErr();
+
+ assertOutputMessageEnd("Already up to date." + EOL + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ }
+
+ @Test
+ public void alreadyUpToDateWithCommitIdTest() throws Exception {
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File setupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(AllIntegrationTests.getProvidedPlatformLocation().toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ setCmdLocation(getRepositoryPath().toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+ RevCommit rev = addAllAndCommit("First commit");
+
+ // Tests referencing a commit using its id.
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, setupFile.getAbsolutePath(), rev.getId().name());
+ Object result = getApp().start(getContext());
+ assertOutputMessageEnd("Already up to date." + EOL + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ assertTrue(getLogicalCommand() instanceof LogicalMergeCommand);
+ LogicalMergeCommand mergeCmd = (LogicalMergeCommand)getLogicalCommand();
+ assertNotNull(mergeCmd.getCommit());
+ }
+
+ @Test
+ public void alreadyUpToDateWithGitDirTest() throws Exception {
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+ addAllAndCommit("First commit");
+
+ // Sets context to be sure were are not in a git repository
+ setCmdLocation(getTestTmpFolder().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File setupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(AllIntegrationTests.getProvidedPlatformLocation().toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Provides the repository using parameter
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, Options.GIT_DIR_OPT, getGitFolderPath().toString(),
+ setupFile.getAbsolutePath(), "master");
+ Object result = getApp().start(getContext());
+
+ printOut();
+ printErr();
+
+ assertOutputMessageEnd("Already up to date." + EOL + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ assertTrue(getLogicalCommand() instanceof LogicalMergeCommand);
+ LogicalMergeCommand mergeCmd = (LogicalMergeCommand)getLogicalCommand();
+ assertNotNull(mergeCmd.getCommit());
+ }
+
+ @Test
+ public void alreadyUpToDateOnRepoSubFolderTest() throws Exception {
+ // Creates some content for the first commit.
+ File project = new ProjectBuilder(this) //
+ .addNewFileContent("newFoler/newFile.txt", "some content") //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+ addAllAndCommit("First commit");
+ // Launches command from subfolder of the git repository
+ setCmdLocation(project.toPath().resolve("newFolder").toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File setupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(AllIntegrationTests.getProvidedPlatformLocation().toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ getContext().addArg(LOGICAL_MERGE_CMD_NAME, setupFile.getAbsolutePath(), "master");
+ Object result = getApp().start(getContext());
+
+ printOut();
+ printErr();
+
+ assertOutputMessageEnd("Already up to date." + EOL + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ assertTrue(getLogicalCommand() instanceof LogicalMergeCommand);
+ LogicalMergeCommand mergeCmd = (LogicalMergeCommand)getLogicalCommand();
+ assertNotNull(mergeCmd.getCommit());
+ }
+
+ @Test
+ public void alreadyUpToDateWithMessageTest() throws Exception {
+ // Creates some content for the first commit.
+ File project = new ProjectBuilder(this) //
+ .addNewFileContent("newFoler/newFile.txt", "some content") //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+ addAllAndCommit("First commit");
+ // Launches command from subfolder of the git repository
+ setCmdLocation(project.toPath().resolve("newFolder").toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File setupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(AllIntegrationTests.getProvidedPlatformLocation().toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ getContext()
+ .addArg(LOGICAL_MERGE_CMD_NAME, setupFile.getAbsolutePath(), "master", "-m", "My message");
+ Object result = getApp().start(getContext());
+
+ printOut();
+ printErr();
+
+ assertOutputMessageEnd("Already up to date." + EOL + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.COMPLETE.code(), result);
+ assertTrue(getLogicalCommand() instanceof LogicalMergeCommand);
+ LogicalMergeCommand mergeCmd = (LogicalMergeCommand)getLogicalCommand();
+ assertNotNull(mergeCmd.getCommit());
+ assertEquals("My message", mergeCmd.getMessage());
+
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolArgumentsCommandTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolArgumentsCommandTest.java
new file mode 100644
index 0000000..8220218
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolArgumentsCommandTest.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeToolCommand.LOGICAL_MERGE_TOOL_CMD_NAME;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalMergeToolArgumentsCommandTest extends AbstractLogicalCommandTest {
+
+ @Override
+ protected String getCommandName() {
+ return LOGICAL_MERGE_TOOL_CMD_NAME;
+ }
+
+ @Override
+ protected String getExpectedUsage() {
+ //@formatter:off
+ return EOL //
+ + "logicalmergetool <setup> [--git-dir gitFolderPath] [--help (-h)] [--show-stack-trace]" + EOL
+ + EOL
+ + " <setup> : Path to the setup file. The setup file is a Oomph" + EOL
+ + " model." + EOL
+ + " --git-dir gitFolderPath : Path to the .git folder of your repository." + EOL
+ + " --help (-h) : Dispays help for this command." + EOL
+ + " --show-stack-trace : Use this option to display java stack trace in" + EOL
+ + " console on error."+ EOL
+ + EOL ; //
+ //@formatter:on
+ }
+
+ @Test
+ public void tooManyArgTest() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(oomphFolderPath.toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Tests referencing a commit using the name of a branch
+ getContext().addArg(getCommandName(), newSetupFile.getAbsolutePath(), "extraArg");
+ Object result = getApp().start(getContext());
+ String expectedOut = "fatal: Too many arguments: extraArg in:" + EOL//
+ + getExpectedUsage() //
+ + EOL; //
+ assertOutput(expectedOut);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+ @Test
+ public void isNotAGitRepoTest() throws Exception {
+ Path myTmpDir = Files.createTempDirectory(getTestTmpFolder(), "NotARepo", new FileAttribute<?>[] {});
+ // Launches command from directory that is not contained by a git repository
+ setCmdLocation(myTmpDir.toString());
+
+ File setupFile = new OomphUserModelBuilder()//
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ getContext().addArg(getCommandName(), setupFile.getAbsolutePath());
+
+ Object result = getApp().start(getContext());
+ assertOutput("fatal: Can't find git repository" + EOL);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolIntegrationTest.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolIntegrationTest.java
new file mode 100644
index 0000000..274b10e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolIntegrationTest.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeToolCommand.LOGICAL_MERGE_TOOL_CMD_NAME;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.nio.file.Path;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.git.pgm.AbstractLogicalAppTest;
+import org.eclipse.emf.compare.git.pgm.LogicalApp;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.suite.AllIntegrationTests;
+import org.eclipse.emf.compare.git.pgm.util.OomphUserModelBuilder;
+import org.eclipse.emf.compare.git.pgm.util.ProjectBuilder;
+import org.eclipse.equinox.app.IApplication;
+import org.junit.Test;
+
+/**
+ * Should only be called from the tycho build since it used the emfcompare-git-pgm update to create the
+ * provided platform.
+ * <p>
+ * If you need to run it locally please set the system variable "emfcompare-git-pgm--updasite" to the location
+ * of update holding emfcompare-git-pgm plugins.
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class LogicalMergeToolIntegrationTest extends AbstractLogicalAppTest {
+
+ @Override
+ protected IApplication buildApp() {
+ return new LogicalApp(URI.createURI(
+ "platform:/fragment/org.eclipse.emf.compare.git.pgm.tests/model/lunaIntegrationTest.setup",
+ false));
+ }
+
+ @Test
+ public void notInConlictState() throws Exception {
+ setCmdLocation(getRepositoryPath().toString());
+
+ Path oomphFolderPath = getTestTmpFolder().resolve("oomphFolder");
+ File newSetupFile = new OomphUserModelBuilder() //
+ .setInstallationTaskLocation(AllIntegrationTests.getProvidedPlatformLocation().toString()) //
+ .setWorkspaceLocation(oomphFolderPath.resolve("ws").toString()) //
+ .saveTo(getTestTmpFolder().resolve("setup.setup").toString());
+
+ // Creates some content for the first commit.
+ new ProjectBuilder(this) //
+ .create(getRepositoryPath().resolve("EmptyProject"));
+
+ addAllAndCommit("First commit");
+
+ // Tests referencing a commit using the name of a branch
+ getContext().addArg(LOGICAL_MERGE_TOOL_CMD_NAME, newSetupFile.getAbsolutePath());
+ Object result = getApp().start(getContext());
+
+ printOut();
+ printErr();
+
+ String expectedOut = "fatal: No conflict to merge" + EOL; //
+ assertOutputMessageEnd(expectedOut);
+ assertEmptyErrorMessage();
+ assertEquals(Returns.ERROR.code(), result);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/util/UtilTests.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/util/UtilTests.java
new file mode 100644
index 0000000..b7d8d25
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/internal/util/UtilTests.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.util;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.CURRENT;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.PARENT;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.SEP;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.toFileWithAbsolutePath;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.Test;
+
+/**
+ * Util tests.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+@SuppressWarnings("nls")
+public class UtilTests {
+
+ @Test
+ public void testRelativePath() throws IOException {
+ String systemTmpDir = System.getProperty("java.io.tmpdir");
+ Path systemTmpDirPath = Paths.get(systemTmpDir);
+ Path d = systemTmpDirPath.resolve("a").resolve("b").resolve("c").resolve("d");
+ File file = toFileWithAbsolutePath(d.toString(), PARENT + SEP + PARENT + SEP + "c");
+ assertEquals(systemTmpDirPath.resolve("a").resolve("b").resolve("c").toString(), file.toString());
+ }
+
+ @Test
+ public void testRelativePath2() throws IOException {
+ String systemTmpDir = System.getProperty("java.io.tmpdir");
+ Path systemTmpDirPath = Paths.get(systemTmpDir);
+ Path d = systemTmpDirPath.resolve("a").resolve("b").resolve("c").resolve("d");
+ File file = toFileWithAbsolutePath(d.toString(), CURRENT + SEP + PARENT + SEP + "d");
+ assertEquals(systemTmpDirPath.resolve("a").resolve("b").resolve("c").resolve("d").toString(), file
+ .toString());
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllCommandLineArguementTests.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllCommandLineArguementTests.java
new file mode 100644
index 0000000..fb3d818
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllCommandLineArguementTests.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.suite;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import junit.textui.TestRunner;
+
+import org.eclipse.emf.compare.git.pgm.LogicalAppTest;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalDiffArgumentsTest;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeCommandArgumentsTest;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeToolArgumentsCommandTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@RunWith(Suite.class)
+@SuiteClasses({LogicalAppTest.class, LogicalMergeCommandArgumentsTest.class,
+ LogicalMergeToolArgumentsCommandTest.class, LogicalDiffArgumentsTest.class })
+public class AllCommandLineArguementTests {
+
+ public static void main(String[] args) {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ return new JUnit4TestAdapter(AllCommandLineArguementTests.class);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllIntegrationTests.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllIntegrationTests.java
new file mode 100644
index 0000000..0ca2bf8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllIntegrationTests.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.suite;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import junit.textui.TestRunner;
+
+import org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalDiffIntegrationTest;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeCommandIntegrationTest;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.LogicalMergeToolIntegrationTest;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * Should only be called from the tycho build since it used the emfcompare-git-pgm update to create the
+ * provided platform.
+ * <p>
+ * If you need to run it locally please set the system variable "emfcompare-git-pgm--updasite" to the location
+ * of update holding emfcompare-git-pgm plugins.
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@RunWith(Suite.class)
+@SuiteClasses({LogicalMergeCommandIntegrationTest.class, LogicalMergeToolIntegrationTest.class,
+ LogicalDiffIntegrationTest.class })
+public class AllIntegrationTests {
+
+ /**
+ * System property to set to the emfcompare-git-pgm update site location.
+ */
+ private static final String EMFCOMPARE_GIT_PGM_UPDASITE_SYS_PROP = "emfcompare-git-pgm--updasite"; //$NON-NLS-1$
+
+ private static final String TMP_DIRECTORY_PREFIX = "emfcompare-git-pgm"; //$NON-NLS-1$
+
+ public static void main(String[] args) {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ return new JUnit4TestAdapter(AllIntegrationTests.class);
+ }
+
+ private static Path providedEclipsePlatformPath;
+
+ /**
+ * Creates a unique location where the provided platform will be located.
+ *
+ * @throws IOException
+ */
+ @BeforeClass
+ public static void provideLocationForProvidedPlatform() throws IOException {
+ providedEclipsePlatformPath = Files.createTempDirectory(TMP_DIRECTORY_PREFIX
+ + "_providedEclipsePlatform", new FileAttribute<?>[] {}); //$NON-NLS-1$
+ String updateSiteLocation = System.getProperty(EMFCOMPARE_GIT_PGM_UPDASITE_SYS_PROP);
+ if (updateSiteLocation == null) {
+ throw new AssertionError("The variable " + EMFCOMPARE_GIT_PGM_UPDASITE_SYS_PROP
+ + " should be defined in the system properties in order to run this test suite.");
+ }
+ }
+
+ @AfterClass
+ public static void deleteProvidedPlatform() throws IOException {
+ if (providedEclipsePlatformPath != null) {
+ FileUtils.delete(providedEclipsePlatformPath.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY);
+ }
+ }
+
+ /**
+ * A unique location where test can share a provided platform.
+ * <p>
+ * All integration tests that do not specifically want to test the providing mechanism can use this shared
+ * location for their provided platform. Using this location will assure that the platform is provided
+ * only once.
+ * </p>
+ *
+ * @return
+ */
+ public static Path getProvidedPlatformLocation() {
+ if (providedEclipsePlatformPath == null) {
+ throw new AssertionError("The integration tests needs to be launched using this suite.");
+ }
+ return providedEclipsePlatformPath;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllLogicalApplicationTests.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllLogicalApplicationTests.java
new file mode 100644
index 0000000..86b932c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllLogicalApplicationTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.suite;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import junit.textui.TestRunner;
+
+import org.eclipse.emf.compare.git.pgm.internal.app.LogicalDiffApplicationTest;
+import org.eclipse.emf.compare.git.pgm.internal.app.LogicalMergeApplicationTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@RunWith(Suite.class)
+@SuiteClasses({LogicalMergeApplicationTest.class, LogicalDiffApplicationTest.class })
+public class AllLogicalApplicationTests {
+
+ public static void main(String[] args) {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ return new JUnit4TestAdapter(AllLogicalApplicationTests.class);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllUtilTests.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllUtilTests.java
new file mode 100644
index 0000000..15e2ccd
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/suite/AllUtilTests.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.suite;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import junit.textui.TestRunner;
+
+import org.eclipse.emf.compare.git.pgm.internal.util.UtilTests;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+@RunWith(Suite.class)
+@SuiteClasses({UtilTests.class })
+public class AllUtilTests {
+
+ public static void main(String[] args) {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ return new JUnit4TestAdapter(AllUtilTests.class);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/MockedApplicationContext.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/MockedApplicationContext.java
new file mode 100644
index 0000000..4d1ef3a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/MockedApplicationContext.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.util;
+
+import com.google.common.collect.ObjectArrays;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.osgi.framework.Bundle;
+
+/**
+ * Mock an {@link IApplicationContext}.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class MockedApplicationContext implements IApplicationContext {
+
+ private static final String ARGS_KEY = "application.args"; //$NON-NLS-1$
+
+ private Map<String, Object> arguments = new HashMap<String, Object>();
+
+ public Map getArguments() {
+ return arguments;
+ }
+
+ public void addArg(String... args) {
+ Object commandLineArgs = arguments.get(ARGS_KEY);
+ if (commandLineArgs == null) {
+ arguments.put(ARGS_KEY, args);
+ } else {
+ arguments.put(ARGS_KEY, ObjectArrays.concat((String[])commandLineArgs, args, String.class));
+ }
+
+ }
+
+ public void applicationRunning() {
+ }
+
+ public String getBrandingApplication() {
+ return null;
+ }
+
+ public String getBrandingName() {
+ return null;
+ }
+
+ public String getBrandingDescription() {
+ return null;
+ }
+
+ public String getBrandingId() {
+ return null;
+ }
+
+ public String getBrandingProperty(String key) {
+ return null;
+ }
+
+ public Bundle getBrandingBundle() {
+ return null;
+ }
+
+ public void setResult(Object result, IApplication application) {
+
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/OomphUserModelBuilder.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/OomphUserModelBuilder.java
new file mode 100644
index 0000000..e2e7255
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/OomphUserModelBuilder.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.stream.Stream;
+
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.oomph.p2.P2Factory;
+import org.eclipse.oomph.resources.ResourcesFactory;
+import org.eclipse.oomph.resources.SourceLocator;
+import org.eclipse.oomph.setup.Index;
+import org.eclipse.oomph.setup.InstallationTask;
+import org.eclipse.oomph.setup.Project;
+import org.eclipse.oomph.setup.ProjectCatalog;
+import org.eclipse.oomph.setup.SetupFactory;
+import org.eclipse.oomph.setup.WorkspaceTask;
+import org.eclipse.oomph.setup.p2.P2Task;
+import org.eclipse.oomph.setup.p2.SetupP2Factory;
+import org.eclipse.oomph.setup.projects.ProjectsFactory;
+import org.eclipse.oomph.setup.projects.ProjectsImportTask;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class OomphUserModelBuilder {
+
+ private String installationTaskLocation;
+
+ private String workspaceLocation;
+
+ private String[] requirements;
+
+ private String[] projectPaths;
+
+ private String[] repositories;
+
+ public OomphUserModelBuilder setInstallationTaskLocation(String installationTaskLocation) {
+ this.installationTaskLocation = installationTaskLocation;
+ return this;
+ }
+
+ public OomphUserModelBuilder setWorkspaceLocation(String workspaceLocation) {
+ this.workspaceLocation = workspaceLocation;
+ return this;
+ }
+
+ public OomphUserModelBuilder setRequirements(String... requirements) {
+ this.requirements = requirements;
+ return this;
+ }
+
+ public OomphUserModelBuilder setProjectPaths(String... projectPaths) {
+ this.projectPaths = projectPaths;
+ return this;
+ }
+
+ public OomphUserModelBuilder setRepositories(String... repositories) {
+ this.repositories = repositories;
+ return this;
+ }
+
+ private String[] getRequirements() {
+ if (requirements == null) {
+ requirements = new String[] {};
+ }
+ return requirements;
+ }
+
+ private String[] getProjectPaths() {
+ if (projectPaths == null) {
+ projectPaths = new String[] {};
+ }
+ return projectPaths;
+ }
+
+ private String[] getRepositories() {
+ if (repositories == null) {
+ repositories = new String[] {};
+ }
+ return repositories;
+ }
+
+ public File saveTo(String setupFilePath) throws IOException {
+ Resource newResource = new XMIResourceImpl();
+ Index index = SetupFactory.eINSTANCE.createIndex();
+ newResource.getContents().add(index);
+
+ ProjectCatalog projectCatalog = SetupFactory.eINSTANCE.createProjectCatalog();
+ index.getProjectCatalogs().add(projectCatalog);
+ if (installationTaskLocation != null) {
+ InstallationTask installationTask = SetupFactory.eINSTANCE.createInstallationTask();
+ projectCatalog.getSetupTasks().add(installationTask);
+ installationTask.setLocation(installationTaskLocation);
+ }
+
+ if (workspaceLocation != null) {
+ WorkspaceTask workspaceTask = SetupFactory.eINSTANCE.createWorkspaceTask();
+ workspaceTask.setLocation(workspaceLocation);
+ projectCatalog.getSetupTasks().add(workspaceTask);
+ }
+
+ Stream.of(getProjectPaths()).distinct().forEach(projectPath -> {
+ Project p = SetupFactory.eINSTANCE.createProject();
+ projectCatalog.getProjects().add(p);
+ ProjectsImportTask importTask = ProjectsFactory.eINSTANCE.createProjectsImportTask();
+ p.getSetupTasks().add(importTask);
+ SourceLocator sourceLocator = ResourcesFactory.eINSTANCE.createSourceLocator();
+ importTask.getSourceLocators().add(sourceLocator);
+ sourceLocator.setRootFolder(projectPath);
+ });
+
+ if (getRepositories().length > 0 || getRequirements().length > 0) {
+ P2Task p2Task = SetupP2Factory.eINSTANCE.createP2Task();
+ projectCatalog.getSetupTasks().add(p2Task);
+ Stream.of(getRequirements()).distinct().forEach(
+ req -> p2Task.getRequirements().add(P2Factory.eINSTANCE.createRequirement(req)));
+ Stream.of(getRepositories()).distinct().forEach(
+ repo -> p2Task.getRepositories().add(P2Factory.eINSTANCE.createRepository(repo)));
+ }
+
+ File setupFile = new File(setupFilePath);
+ FileOutputStream fileOutputStram = new FileOutputStream(setupFile);
+ try {
+ newResource.save(fileOutputStram, null);
+ } finally {
+ fileOutputStram.close();
+ }
+ return setupFile;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/ProjectBuilder.java b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/ProjectBuilder.java
new file mode 100644
index 0000000..54292c9
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm.tests/src/org/eclipse/emf/compare/git/pgm/util/ProjectBuilder.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.util;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import com.google.common.base.Preconditions;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("nls")
+public class ProjectBuilder {
+
+ private final Object startingPointForRelativePath;
+
+ private List<String> relativePathContentToCopy = new ArrayList<>();
+
+ private Map<String, String> newFilesContent = new HashMap<>();
+
+ private boolean clean = false;
+
+ public ProjectBuilder(Object startingPointForRelativePath) {
+ super();
+ this.startingPointForRelativePath = startingPointForRelativePath;
+ }
+
+ public ProjectBuilder addContentToCopy(String relativePathContent) {
+ relativePathContentToCopy.add(relativePathContent);
+ return this;
+ }
+
+ public ProjectBuilder addNewFileContent(String relativePath, String content) {
+ newFilesContent.put(relativePath, content);
+ return this;
+ }
+
+ public ProjectBuilder clean(boolean needClean) {
+ this.clean = needClean;
+ return this;
+ }
+
+ private void cleanBeforeCreate(Path to) {
+ File file = to.toFile();
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ for (File f : files) {
+ cleanBeforeCreate(f.toPath());
+ }
+ }
+ file.delete();
+ }
+
+ }
+
+ private String getFileName(String relativePath) {
+ return FileSystems.getDefault().getPath(relativePath).getFileName().toString();
+ }
+
+ public File create(Path to) throws IOException {
+ Preconditions.checkNotNull(to);
+ if (clean) {
+ cleanBeforeCreate(to);
+ }
+ File project = createProject(to);
+
+ // Creates new file with content
+ for (Entry<String, String> newFileEntry : newFilesContent.entrySet()) {
+ createFile(project.toPath().resolve(newFileEntry.getKey()), newFileEntry.getValue());
+ }
+
+ // Creates new content from copy
+ for (String relativePath : relativePathContentToCopy) {
+ InputStream stream = startingPointForRelativePath.getClass().getResourceAsStream(relativePath);
+ assertNotNull(stream);
+ try {
+ Files.copy(stream, to.resolve(getFileName(relativePath)), StandardCopyOption.REPLACE_EXISTING);
+ } finally {
+ stream.close();
+ }
+ }
+
+ return project;
+ }
+
+ protected File createProject(Path projectPath) throws IOException {
+ File project = projectPath.toFile();
+ if (!project.mkdirs()) {
+ throw new AssertionError("Can create a project at " + projectPath.toString());
+ }
+ // Creates ".project" file
+ File projectFile = projectPath.resolve(".project").toFile();
+ if (projectFile.exists()) {
+ projectFile.delete();
+ }
+ projectFile.createNewFile();
+ PrintWriter writer = new PrintWriter(projectFile);
+ StringBuilder content = new StringBuilder();
+ content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append(EOL);
+ content.append("<projectDescription>").append(EOL);
+ content.append("<name>").append(projectPath.getFileName()).append("</name>").append(EOL);
+ content.append("<comment></comment>").append(EOL);
+ content.append("<projects></projects>").append(EOL);
+ content.append("<buildSpec></buildSpec>").append(EOL);
+ content.append("<natures></natures>").append(EOL);
+ content.append("</projectDescription>").append(EOL);
+ writer.print(content.toString());
+ writer.close();
+ assertFalse(writer.checkError());
+ return project;
+ }
+
+ protected File createFile(Path path, String content) throws FileNotFoundException,
+ UnsupportedEncodingException {
+ File result = path.toFile();
+ path.getParent().toFile().mkdirs();
+ PrintWriter writer = new PrintWriter(result, "UTF-8"); //$NON-NLS-1$
+ writer.println(content);
+ writer.close();
+ assertFalse(writer.checkError());
+ return result;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.checkstyle b/plugins/org.eclipse.emf.compare.git.pgm/.checkstyle
new file mode 100644
index 0000000..9d20703
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.checkstyle
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+ <local-check-config name="EMF Compare" location="/org.eclipse.emf.compare-parent/codeStyle/EMFCompareCheckstyle5Configuration.xml" type="project" description="">
+ <additional-data name="protect-config-file" value="false"/>
+ </local-check-config>
+ <fileset name="all" enabled="true" check-config-name="EMF Compare" local="true">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+ <filter name="FilesFromPackage" enabled="true">
+ <filter-data value="src-gen"/>
+ </filter>
+</fileset-config>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.classpath b/plugins/org.eclipse.emf.compare.git.pgm/.classpath
new file mode 100644
index 0000000..098194c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.project b/plugins/org.eclipse.emf.compare.git.pgm/.project
new file mode 100644
index 0000000..0ec80cf
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.compare.git.pgm</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.settings/edu.umd.cs.findbugs.core.prefs b/plugins/org.eclipse.emf.compare.git.pgm/.settings/edu.umd.cs.findbugs.core.prefs
new file mode 100644
index 0000000..1fab655
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.settings/edu.umd.cs.findbugs.core.prefs
@@ -0,0 +1,132 @@
+#FindBugs User Preferences
+#Tue Mar 12 08:11:54 CET 2013
+cloud_id=edu.umd.cs.findbugs.cloud.doNothingCloud
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorAtomicityProblem=AtomicityProblem|true
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false
+detectorCheckExpectedWarnings=CheckExpectedWarnings|false
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|true
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDefaultEncodingDetector=DefaultEncodingDetector|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorExplicitSerialization=ExplicitSerialization|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUseOfNonSerializableValue=FindUseOfNonSerializableValue|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInitializeNonnullFieldsInConstructor=InitializeNonnullFieldsInConstructor|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorIntCast2LongAsInstant=IntCast2LongAsInstant|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false|15
+filter_settings_neg=NOISE,I18N,EXPERIMENTAL|
+run_at_full_build=true
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs b/plugins/org.eclipse.emf.compare.git.pgm/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs
new file mode 100644
index 0000000..4235f76
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+edu.umd.cs.findbugs.plugin.eclipse.findbugsMarkerScariest=Error
+edu.umd.cs.findbugs.plugin.eclipse.findbugsMarkerScary=Error
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.core.runtime.prefs b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..40cb436
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,374 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis=disabled
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=110
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=110
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=false
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..4e1442e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,60 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_EMF Compare
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=fr;com;java;javax;org;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.pde.api.tools.prefs b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..01461e0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,97 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Warning
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Warning
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Warning
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Warning
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Warning
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Warning
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Warning
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Warning
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Warning
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Warning
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Warning
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Warning
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Warning
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Warning
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Warning
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Warning
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Warning
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Warning
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Warning
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Warning
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Warning
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Warning
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Warning
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Warning
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Warning
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Warning
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Warning
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning
+MISSING_EE_DESCRIPTIONS=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Warning
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Warning
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Warning
+malformed_since_tag=Warning
+missing_since_tag=Warning
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.git.pgm/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..bb35c76
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/META-INF/MANIFEST.MF
@@ -0,0 +1,31 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: EMF Compare Git PGM
+Bundle-SymbolicName: org.eclipse.emf.compare.git.pgm;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.equinox.p2.metadata;bundle-version="2.0.0",
+ org.eclipse.jgit;bundle-version="3.4.0",
+ org.eclipse.team.core;bundle-version="3.0.0",
+ org.eclipse.egit.core;bundle-version="3.4.0",
+ org.eclipse.oomph.util;bundle-version="1.0.0",
+ org.eclipse.oomph.base.edit;bundle-version="1.0.0",
+ org.eclipse.oomph.setup;bundle-version="1.0.0",
+ org.eclipse.oomph.setup.core;bundle-version="1.0.0",
+ org.eclipse.oomph.setup.projects;bundle-version="1.0.0",
+ org.eclipse.oomph.setup.p2;bundle-version="1.0.0",
+ org.eclipse.emf.compare;bundle-version="3.1.0",
+ org.eclipse.emf.compare.ide.ui;bundle-version="4.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Import-Package: com.google.common.base;version="15.0.0",
+ com.google.common.collect;version="15.0.0",
+ org.kohsuke.args4j;version="[2.0.12,2.1.0)",
+ org.kohsuke.args4j.spi;version="[2.0.12,2.1.0)"
+Export-Package: org.eclipse.emf.compare.git.pgm;mandatory:="org.eclipse.emf.compare.git.pgm";org.eclipse.emf.compare.git.pgm:=split;x-friends:="org.eclipse.emf.compare.git.pgm.tests",
+ org.eclipse.emf.compare.git.pgm.internal;uses:="org.eclipse.core.runtime,org.eclipse.oomph.setup.log,org.eclipse.oomph.setup",
+ org.eclipse.emf.compare.git.pgm.internal.app,
+ org.eclipse.emf.compare.git.pgm.internal.args,
+ org.eclipse.emf.compare.git.pgm.internal.cmd;x-friends:="org.eclipse.emf.compare.git.pgm.tests",
+ org.eclipse.emf.compare.git.pgm.internal.exception,
+ org.eclipse.emf.compare.git.pgm.internal.util
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/about.html b/plugins/org.eclipse.emf.compare.git.pgm/about.html
new file mode 100644
index 0000000..5507b29
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/about.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Foundation Software User Agreement</title>
+</head>
+
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>April 14, 2010</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+ repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+ Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or
+ other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to
+ install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a
+ href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+ ("Specification").</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+ applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+ in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+ Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+ <li>A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology
+ on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based
+ product.</li>
+ <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+ accessed and copied to the Target Machine.</li>
+ <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+ Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target
+ Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+ the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+ indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/build.properties b/plugins/org.eclipse.emf.compare.git.pgm/build.properties
new file mode 100644
index 0000000..669dad4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .,\
+ model/
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/model/kepler.setup b/plugins/org.eclipse.emf.compare.git.pgm/model/kepler.setup
new file mode 100644
index 0000000..90b1dc2
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/model/kepler.setup
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<setup:Index
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:setup="http://www.eclipse.org/oomph/setup/1.0"
+ xmlns:setup.p2="http://www.eclipse.org/oomph/setup/p2/1.0"
+ name="org.eclipse"
+ label="Eclipse.org">
+ <productCatalog
+ name="org.eclipse.products"
+ label="Eclipse.org">
+ <setupTask
+ xsi:type="setup.p2:P2Task"
+ id="P2 oomph"
+ licenseConfirmationDisabled="true">
+ <requirement
+ name="org.eclipse.emf.sdk.feature.group"/>
+ <requirement
+ name="org.eclipse.egit"/>
+ <requirement
+ name="org.eclipse.egit.core"/>
+ <requirement
+ name="org.eclipse.pde.api.tools.ee.feature.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.core.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.jdt.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.git.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.projects.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.p2.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.version.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.projectcopy.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.resources"/>
+ <requirement
+ name="org.eclipse.emf.compare.feature.group"/>
+ <requirement
+ name="org.eclipse.emf.compare.ide.ui.feature.group"/>
+ <requirement
+ name="org.kohsuke.args4j"/>
+ <requirement
+ name="com.google.guava"/>
+ <requirement
+ name="org.eclipse.emf.compare.git.pgm.feature.feature.group"/>
+ <repository
+ url="http://download.eclipse.org/releases/kepler/201402280900"/>
+ <repository
+ url="file:/D:/tests/egitLogical/org.eclipse.egit.repository-3.5.0-SNAPSHOT"/>
+ <repository
+ url="http://adaussy.github.io/EMFCompareGitPGM/"/>
+ <repository
+ url="http://download.eclipse.org/modeling/emf/emf/updates/2.10/core/R201405190339"/>
+ <repository
+ url="https://hudson.eclipse.org/oomph/job/integration/lastSuccessfulBuild/artifact/updates/"/>
+ <repository
+ url="http://download.eclipse.org/modeling/emf/compare/updates/nightly/latest"/>
+ <repository
+ url="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/"/>
+ </setupTask>
+ <product
+ name="epp.package.standard"
+ label="Eclipse Standard/SDK">
+ <version
+ name="kepler"
+ label="Kepler">
+ <setupTask
+ xsi:type="setup.p2:P2Task"
+ id="P2 Eclipse"
+ licenseConfirmationDisabled="true">
+ <requirement
+ name="epp.package.standard"
+ versionRange="[2.0.0,2.1.0)"/>
+ <requirement
+ name="org.eclipse.platform.feature.group"
+ versionRange="[4.3.0,4.4.0)"/>
+ <requirement
+ name="org.eclipse.rcp.feature.group"
+ versionRange="[4.3.0,4.4.0)"/>
+ <requirement
+ name="org.eclipse.jdt.feature.group"
+ versionRange="[3.9.0,3.10.0)"/>
+ <requirement
+ name="org.eclipse.pde.feature.group"
+ versionRange="[3.9.0,3.10.0)"/>
+ <repository
+ url="http://download.eclipse.org/technology/epp/packages/kepler"/>
+ <repository
+ url="http://download.eclipse.org/releases/kepler/201402280900"/>
+ </setupTask>
+ </version>
+ </product>
+ <description>All the Eclipse Packaging Products at Eclipse.org</description>
+ </productCatalog>
+</setup:Index>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/model/luna.setup b/plugins/org.eclipse.emf.compare.git.pgm/model/luna.setup
new file mode 100644
index 0000000..240cfb6
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/model/luna.setup
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<setup:Index
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:setup="http://www.eclipse.org/oomph/setup/1.0"
+ xmlns:setup.p2="http://www.eclipse.org/oomph/setup/p2/1.0"
+ name="org.eclipse"
+ label="Eclipse.org">
+ <productCatalog
+ name="org.eclipse.products"
+ label="Eclipse.org">
+ <setupTask
+ xsi:type="setup.p2:P2Task"
+ id="P2 oomph"
+ licenseConfirmationDisabled="true">
+ <requirement
+ name="org.eclipse.emf.sdk.feature.group"/>
+ <requirement
+ name="org.eclipse.egit"/>
+ <requirementfile
+ name="org.eclipse.egit.core"/>
+ <requirement
+ name="org.eclipse.pde.api.tools.ee.feature.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.core.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.jdt.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.git.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.setup.projects.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.p2.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.version.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.projectcopy.feature.group"/>
+ <requirement
+ name="org.eclipse.oomph.resources"/>
+ <requirement
+ name="org.eclipse.emf.compare.feature.group"/>
+ <requirement
+ name="org.eclipse.emf.compare.ide.ui.feature.group"/>
+ <requirement
+ name="org.kohsuke.args4j"/>
+ <requirement
+ name="com.google.guava"/>
+ <requirement
+ name="org.eclipse.emf.compare.git.pgm.feature.feature.group"/>
+ <repository
+ url="http://download.eclipse.org/releases/luna/201406250900"/>
+ <repository
+ url="http://ericssonegit.ci.obeo.fr:8180/jenkins/job/egit-logical/lastSuccessfulBuild/artifact/org.eclipse.egit.repository/target/repository/"/>
+ <repository
+ url="http://adaussy.github.io/EMFCompareGitPGM/"/>
+ <repository
+ url="http://download.eclipse.org/modeling/emf/emf/updates/2.10/core/R201405190339"/>
+ <repository
+ url="https://hudson.eclipse.org/oomph/job/integration/lastSuccessfulBuild/artifact/updates/"/>
+ <repository
+ url="http://download.eclipse.org/modeling/emf/compare/updates/nightly/latest"/>
+ <repository
+ url="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/"/>
+ </setupTask>
+ <product
+ name="epp.package.standard"
+ label="Eclipse Standard/SDK">
+ <version
+ name="luna"
+ label="Luna">
+ <setupTask
+ xsi:type="setup.p2:P2Task"
+ id="P2 Eclipse"
+ licenseConfirmationDisabled="true">
+ <requirement
+ name="epp.package.standard"
+ versionRange="[4.4.0,4.5.0)"/>
+ <requirement
+ name="org.eclipse.platform.feature.group"
+ versionRange="[4.4.0,4.5.0)"/>
+ <requirement
+ name="org.eclipse.rcp.feature.group"
+ versionRange="[4.4.0,4.5.0)"/>
+ <requirement
+ name="org.eclipse.jdt.feature.group"
+ versionRange="[3.10.0,3.11.0)"/>
+ <requirement
+ name="org.eclipse.pde.feature.group"
+ versionRange="[3.9.0,3.11.0)"/>
+ <repository
+ url="http://download.eclipse.org/technology/epp/packages/luna"/>
+ <repository
+ url="http://download.eclipse.org/releases/luna/201406250900"/>
+ </setupTask>
+ </version>
+ </product>
+ <description>All the Eclipse Packaging Products at Eclipse.org</description>
+ </productCatalog>
+</setup:Index>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/plugin.xml b/plugins/org.eclipse.emf.compare.git.pgm/plugin.xml
new file mode 100644
index 0000000..258bb49
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/plugin.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="emf.compare.git.launcherApp"
+ point="org.eclipse.core.runtime.applications">
+ <application>
+ <run
+ class="org.eclipse.emf.compare.git.pgm.LogicalApp">
+ </run>
+ </application>
+ </extension>
+ <extension
+ id="emf.compare.git.logicaldiff"
+ point="org.eclipse.core.runtime.applications">
+ <application>
+ <run
+ class="org.eclipse.emf.compare.git.pgm.internal.app.LogicalDiffApplication">
+ </run>
+ </application>
+ </extension>
+ <extension
+ id="emf.compare.git.logicalmerge"
+ point="org.eclipse.core.runtime.applications">
+ <application>
+ <run
+ class="org.eclipse.emf.compare.git.pgm.internal.app.LogicalMergeApplication">
+ </run>
+ </application>
+ </extension>
+ <extension
+ id="org.eclipse.emf.compare.git.pgm.product"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="emf.compare.git.launcherApp"
+ name="EMF Compare Git PGM">
+ </product>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/pom.xml b/plugins/org.eclipse.emf.compare.git.pgm/pom.xml
new file mode 100644
index 0000000..38745b1
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/pom.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm.parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../org.eclipse.emf.compare.git.pgm.parent/</relativePath>
+ </parent>
+ <groupId>org.eclipse.emf.compare.git.pgm</groupId>
+ <artifactId>org.eclipse.emf.compare.git.pgm</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project>
\ No newline at end of file
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/LogicalApp.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/LogicalApp.java
new file mode 100644
index 0000000..a27a25b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/LogicalApp.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm;
+
+import static org.eclipse.emf.compare.git.pgm.Returns.COMPLETE;
+import static org.eclipse.emf.compare.git.pgm.Returns.ERROR;
+import static org.eclipse.emf.compare.git.pgm.internal.Options.HELP_OPT;
+import static org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType.FATAL;
+
+import com.google.common.collect.Lists;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.git.pgm.internal.args.LogicalCommandHandler;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommand;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.CommandFactory;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.ExampleMode;
+import org.kohsuke.args4j.Option;
+
+/**
+ * <h4>Name</h4>
+ * <p>
+ * logicalApp - Logical Application
+ * </p>
+ * <h4>Synopsis</h4>
+ * <p>
+ * logicalapp --help <command> <commandArgs...>
+ * <h4>Description</h4>
+ * <p>
+ * This application is a command line tool handling logical commands. See {@link CommandFactory} for a
+ * detailed list of handled commands.
+ * </p>
+ * <p>
+ * This class is the main entrance for the this application.
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class LogicalApp implements IApplication {
+
+ /**
+ * Holds true if the user has requested help for this app.
+ */
+ @Option(name = HELP_OPT, usage = "Displays help for this command.", aliases = {"-h" })
+ private boolean help;
+
+ /**
+ * Holds the logical command to be run.
+ */
+ @Argument(index = 0, metaVar = "cmd", required = true, handler = LogicalCommandHandler.class)
+ private AbstractLogicalCommand logicalCommand;
+
+ /**
+ * Other arguments used in logical commands.
+ */
+ @Argument(index = 1, metaVar = "args")
+ private List<String> arguments = new ArrayList<String>();
+
+ private final URI environmentSetupURI;
+
+ public LogicalApp() {
+ this(URI.createPlatformPluginURI("/org.eclipse.emf.compare.git.pgm/model/luna.setup", true)); //$NON-NLS-1$
+ }
+
+ public LogicalApp(URI environmentURI) {
+ environmentSetupURI = environmentURI;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
+ */
+ public Object start(IApplicationContext context) throws Exception {
+ // Prevents vm args if the application exits on something different that 0
+ System.setProperty(IApplicationContext.EXIT_DATA_PROPERTY, "");
+ @SuppressWarnings("rawtypes")
+ final Map args = context.getArguments();
+ String[] appArg = (String[])args.get("application.args"); //$NON-NLS-1$
+ if (appArg == null) {
+ appArg = new String[] {};
+ }
+ Object returnCode;
+ try {
+ returnCode = execute(appArg);
+ } catch (Die error) {
+ final boolean showStackTrace;
+ if (logicalCommand != null) {
+ showStackTrace = logicalCommand.isShowStackTrace();
+ } else {
+ showStackTrace = false;
+ }
+ return EMFCompareGitPGMUtil.handleDieError(error, showStackTrace);
+ }
+
+ if (System.out.checkError() || System.err.checkError()) {
+ // TODO improve this
+ System.out.println("Unknown error");
+ returnCode = ERROR;
+ }
+ return returnCode;
+ }
+
+ /**
+ * Builds and executes the logical command.
+ *
+ * @param argv
+ * application arguments.
+ * @return {@link Returns}
+ * @throws Die
+ * @throws IOException
+ */
+ private Object execute(final String[] argv) throws Die, IOException {
+ final CmdLineParser clp = new CmdLineParser(this);
+ try {
+ clp.parseArgument(argv);
+ } catch (CmdLineException err) {
+ // Incorrect arguments
+ if (argv.length > 0 && !help) {
+ throw new DiesOn(FATAL).displaying(err.getMessage()).ready();
+ }
+ }
+ // User is requiring help.
+ if (help) {
+ printHelp(clp, new PrintWriter(System.out));
+ return COMPLETE;
+ }
+ // If the user has provided no argument, display usage and and return error code.
+ if (argv.length == 0) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter printWritter = new PrintWriter(out);
+ printHelp(clp, printWritter);
+ printWritter.close();
+ throw new DiesOn(FATAL).displaying(out.toString()).ready();
+ }
+
+ logicalCommand.build(arguments, environmentSetupURI);
+
+ Object returnCode;
+ try {
+ // Do not catch exception but flush what was currently writing the command
+ returnCode = logicalCommand.execute();
+ } finally {
+ logicalCommand.flushOutW();
+ }
+ return returnCode;
+ }
+
+ /**
+ * Print the help message to the user.
+ *
+ * @param clp
+ * parser
+ * @param printWritter
+ * {@link PrintWriter}.
+ */
+ private void printHelp(CmdLineParser clp, PrintWriter printWritter) {
+ final String ex = clp.printExample(ExampleMode.ALL);
+ printWritter.println("logicalApp" + ex + " command [ARG ...]"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (help) {
+ printWritter.println();
+ clp.printUsage(printWritter, null);
+ }
+ if (logicalCommand == null) {
+ printWritter.println();
+ printWritter.println("Available commands are:");
+ List<String> availableCommands = Lists.newArrayList(CommandFactory.getInstance()
+ .getAvailableCmd());
+ Collections.sort(availableCommands);
+ for (String cmdName : availableCommands) {
+ printWritter.println(cmdName);
+ }
+ }
+ printWritter.flush();
+ }
+
+ // For testing purpose.
+ AbstractLogicalCommand getLogicalCommand() {
+ return logicalCommand;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.equinox.app.IApplication#stop()
+ */
+ public void stop() {
+ // nothing to do
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/Returns.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/Returns.java
new file mode 100644
index 0000000..7ca5003
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/Returns.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm;
+
+import org.eclipse.equinox.app.IApplication;
+
+/**
+ * List of all code that {@link org.eclipse.emf.compare.git.pgm.LogicalApp} can return.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public enum Returns {
+ /**
+ * Action terminated normally.
+ */
+ COMPLETE(IApplication.EXIT_OK),
+ /**
+ * The action has not finished completely.
+ */
+ ABORTED(Integer.valueOf(1)),
+ /**
+ * An error has occurred.
+ */
+ ERROR(Integer.valueOf(128));
+
+ private final Integer code;
+
+ private Returns(Integer code) {
+ this.code = code;
+ }
+
+ public final Integer code() {
+ return code;
+ }
+
+ public static Returns valueOf(int code) {
+ for (Returns r : Returns.values()) {
+ if (r.code().equals(Integer.valueOf(code))) {
+ return r;
+ }
+ }
+ System.err.println(code + " is not a valid return code");
+ return ERROR;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/Messages.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/Messages.java
new file mode 100644
index 0000000..55df25a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/Messages.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal;
+
+/**
+ * Class holding all messages.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public final class Messages {
+ /**
+ * Message displayed when an uncatch IO error is raised.
+ */
+ public static final String UNKOWN_IO_ERROR_MESSAGE = "Unkown IO error";
+
+ /**
+ * Message displayed when the repository can no be found.
+ */
+ public static final String CAN_T_FIND_GIT_REPOSITORY_MESSAGE = "Can't find git repository";
+
+ /**
+ * Constructor.
+ */
+ private Messages() {
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/Options.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/Options.java
new file mode 100644
index 0000000..d9caf7d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/Options.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal;
+
+/**
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class Options {
+
+ private Options() {
+ }
+
+ public static final String HELP_OPT = "--help"; //$NON-NLS-1$
+
+ public static final String SHOW_STACK_TRACE_OPT = "--show-stack-trace"; //$NON-NLS-1$
+
+ public static final String GIT_DIR_OPT = "--git-dir"; //$NON-NLS-1$
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/ProgressPageLog.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/ProgressPageLog.java
new file mode 100644
index 0000000..d88626f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/ProgressPageLog.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal;
+
+import java.io.PrintStream;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.oomph.setup.SetupTask;
+import org.eclipse.oomph.setup.log.ProgressLog;
+import org.eclipse.oomph.util.OomphPlugin;
+
+/**
+ * Specific {@link ProgressLog}.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class ProgressPageLog implements ProgressLog {
+
+ private final PrintStream out;
+
+ public ProgressPageLog(PrintStream out) {
+ super();
+ this.out = out;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public boolean isCanceled() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public void log(String line) {
+ out.println(line);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public void log(String line, boolean filter) {
+ /*
+ * No documentation is available on the filter parameter. However empirical tests show that filter is
+ * set to false when logging IStatus or exceptions. In our case we do not want to show that kind of
+ * information on the progress page log. It will be displayed later on the application is the
+ * --show-stack-trace option is set to true.
+ */
+ if (filter) {
+ out.println(line);
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public void log(IStatus status) {
+ String string = OomphPlugin.toString(status);
+ log(string, false);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public void log(Throwable t) {
+ String string = OomphPlugin.toString(t);
+ log(string, false);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public void task(SetupTask setupTask) {
+ }
+
+ public void setTerminating() {
+
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/AbstractLogicalApplication.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/AbstractLogicalApplication.java
new file mode 100644
index 0000000..e898424
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/AbstractLogicalApplication.java
@@ -0,0 +1,486 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.app;
+
+import static org.eclipse.emf.compare.git.pgm.internal.Options.SHOW_STACK_TRACE_OPT;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EMPTY_STRING;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.SEP;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.toFileWithAbsolutePath;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.egit.core.JobFamilies;
+import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.ProgressPageLog;
+import org.eclipse.emf.compare.git.pgm.internal.args.CmdLineParserRepositoryBuilder;
+import org.eclipse.emf.compare.git.pgm.internal.args.GitDirHandler;
+import org.eclipse.emf.compare.git.pgm.internal.args.SetupFileOptionHandler;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil;
+import org.eclipse.emf.compare.ide.ui.internal.logical.EMFModelProvider;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.equinox.p2.metadata.ILicense;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+import org.eclipse.oomph.base.provider.BaseEditUtil;
+import org.eclipse.oomph.internal.setup.SetupPrompter;
+import org.eclipse.oomph.resources.ResourcesFactory;
+import org.eclipse.oomph.resources.SourceLocator;
+import org.eclipse.oomph.setup.Index;
+import org.eclipse.oomph.setup.Project;
+import org.eclipse.oomph.setup.ProjectCatalog;
+import org.eclipse.oomph.setup.SetupPackage;
+import org.eclipse.oomph.setup.SetupTask;
+import org.eclipse.oomph.setup.Trigger;
+import org.eclipse.oomph.setup.internal.core.SetupContext;
+import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer;
+import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
+import org.eclipse.oomph.setup.internal.core.util.SetupUtil;
+import org.eclipse.oomph.setup.projects.ProjectsFactory;
+import org.eclipse.oomph.setup.projects.ProjectsImportTask;
+import org.eclipse.oomph.util.Confirmer;
+import org.eclipse.oomph.util.IOUtil;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.Option;
+
+/**
+ * Abstract class for any logical application.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+@SuppressWarnings("restriction")
+public abstract class AbstractLogicalApplication implements IApplication {
+
+ /**
+ * Holds git directory location.
+ */
+ @Argument(index = 0, metaVar = "gitFolderPath", usage = "Path to the .git folder of your repository.", handler = GitDirHandler.class)
+ protected String gitdir;
+
+ /**
+ * Holds the Oomph model setup file.
+ */
+ @Argument(index = 1, metaVar = "<setup>", required = true, usage = "Path to the setup file. The setup file is a Oomph model.", handler = SetupFileOptionHandler.class)
+ protected File setupFile;
+
+ /**
+ * Holds true if the java stack trace should be displayed in the console if any.
+ */
+ @Option(name = SHOW_STACK_TRACE_OPT, usage = "Use this option to display java stack trace in console on error.")
+ private boolean showStackTrace;
+
+ /**
+ * Logs any message from oomph.
+ */
+ protected ProgressPageLog progressPageLog;
+
+ /**
+ * Git repository for this command to be executed in.
+ */
+ protected Repository repo;
+
+ /**
+ * Performs the logical git command (diff or merge).
+ *
+ * @return a {@link org.eclipse.emf.compare.git.pgm.Returns}.
+ */
+ protected abstract Integer performGitCommand() throws Die;
+
+ /**
+ * Creates and configure the setup task performer to execute the imports of projects referenced in the
+ * user setup model. Then call the {@link #performGitCommand()}.
+ *
+ * @return a {@link org.eclipse.emf.compare.git.pgm.Returns}.
+ * @throws IOException
+ * @throws Die
+ */
+ protected void performStartup() throws Die {
+ ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(BaseEditUtil
+ .createAdapterFactory());
+
+ ResourceSet rs = SetupUtil.createResourceSet();
+ rs.eAdapters().add(
+ new AdapterFactoryEditingDomain.EditingDomainProvider(new AdapterFactoryEditingDomain(
+ adapterFactory, null, rs)));
+ rs.getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING,
+ ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
+
+ URI startupSetupURI = URI.createFileURI(setupFile.getAbsolutePath());
+ Resource startupSetupResource = rs.getResource(startupSetupURI, true);
+
+ Index startupSetupIndex = (Index)EcoreUtil.getObjectByType(startupSetupResource.getContents(),
+ SetupPackage.Literals.INDEX);
+
+ SetupContext setupContext = SetupContext.createInstallationAndUser(rs);
+
+ try {
+ Trigger triggerStartup = Trigger.STARTUP;
+ URIConverter uriConverter = rs.getURIConverter();
+ SetupTaskPerformer performerStartup = SetupTaskPerformer.create(uriConverter,
+ SetupPrompter.CANCEL, triggerStartup, setupContext, false);
+ Confirmer confirmer = Confirmer.ACCEPT;
+ performerStartup.put(ILicense.class, confirmer);
+ performerStartup.put(Certificate.class, confirmer);
+
+ progressPageLog = new ProgressPageLog(System.out);
+ performerStartup.setProgress(progressPageLog);
+
+ cleanWorkspace();
+
+ handleImportProjects(startupSetupIndex, performerStartup);
+
+ performerStartup.perform();
+
+ validatePerform(performerStartup);
+
+ waitEgitJobs();
+ } catch (Die e) {
+ throw e;
+ } catch (Exception e) {
+ final String message;
+ if (e instanceof CoreException) {
+ message = EMFCompareGitPGMUtil.getStatusMessage(((CoreException)e).getStatus());
+ } else {
+ message = "Error during Oomph operation";
+ }
+ throw new DiesOn(DeathType.FATAL).duedTo(e).displaying(message).ready();
+ }
+ }
+
+ /**
+ * Handle ProjectsImport tasks.
+ *
+ * @param startupSetupIndex
+ * the root of the setup model.
+ * @param performerStartup
+ * the SetupTaskPerformer.
+ */
+ private void handleImportProjects(Index startupSetupIndex, SetupTaskPerformer performerStartup) {
+ List<ProjectsImportTask> projectToImport = new ArrayList<ProjectsImportTask>();
+
+ // Import Projects & execute other startup tasks.
+ final String resourcePath = startupSetupIndex.eResource().getURI().toFileString();
+ final String resourceBasePath = resourcePath.substring(0, resourcePath.lastIndexOf(SEP));
+ for (ProjectCatalog projectCatalog : startupSetupIndex.getProjectCatalogs()) {
+ for (SetupTask setupTask : projectCatalog.getSetupTasks()) {
+ if (setupTask instanceof ProjectsImportTask) {
+ // Convert locations of projects to absolute paths.
+ ProjectsImportTask importTask = createCopyWithAbsolutePath((ProjectsImportTask)setupTask,
+ resourceBasePath);
+ performerStartup.getTriggeredSetupTasks().add(importTask);
+ projectToImport.add(importTask);
+ } else {
+ performerStartup.getTriggeredSetupTasks().add(setupTask);
+ }
+ }
+ for (Project project : projectCatalog.getProjects()) {
+ for (SetupTask setupTask : project.getSetupTasks()) {
+ if (setupTask instanceof ProjectsImportTask) {
+ // Convert locations of projects to absolute paths.
+ ProjectsImportTask importTask = createCopyWithAbsolutePath(
+ (ProjectsImportTask)setupTask, resourceBasePath);
+ performerStartup.getTriggeredSetupTasks().add(importTask);
+ projectToImport.add(importTask);
+ } else {
+ performerStartup.getTriggeredSetupTasks().add(setupTask);
+ }
+ }
+ }
+ }
+
+ // If no ProjectsImportTask found, import all projects in repo
+ if (projectToImport.isEmpty()) {
+ ProjectsImportTask importTask = ProjectsFactory.eINSTANCE.createProjectsImportTask();
+ SourceLocator sourceLocator = ResourcesFactory.eINSTANCE.createSourceLocator(repo.getWorkTree()
+ .getAbsolutePath(), false);
+ importTask.getSourceLocators().add(sourceLocator);
+ performerStartup.getTriggeredSetupTasks().add(importTask);
+ }
+ }
+
+ /**
+ * Create copy of the projects import task with all root folders of source locators convert in absolute
+ * paths.
+ *
+ * @param task
+ * the {@link ProjectsImportTask} to copy.
+ * @param resourceBasePath
+ * the resourceBasePath needed to compute absolute paths.
+ * @return copy of the projects import task with all root folders of source locators convert in absolute
+ * paths.
+ */
+ private ProjectsImportTask createCopyWithAbsolutePath(ProjectsImportTask task,
+ final String resourceBasePath) {
+ ProjectsImportTask importTask = EcoreUtil.copy(task);
+ EList<SourceLocator> sourceLocators = importTask.getSourceLocators();
+ for (SourceLocator sourceLocator : sourceLocators) {
+ String projectAbsolutePath = toFileWithAbsolutePath(resourceBasePath,
+ sourceLocator.getRootFolder()).toString();
+ sourceLocator.setRootFolder(projectAbsolutePath);
+ }
+ return importTask;
+ }
+
+ /**
+ * @param performerStartup
+ * @throws Die
+ */
+ private void validatePerform(SetupTaskPerformer performerStartup) throws Die {
+ if (!performerStartup.hasSuccessfullyPerformed()) {
+ throw new DiesOn(DeathType.FATAL).displaying("Error during Oomph operation: Failure").ready();
+ }
+
+ if (performerStartup.isCanceled()) {
+ throw new DiesOn(DeathType.FATAL).displaying("Error during Oomph operation: Canceled").ready();
+ }
+
+ if (performerStartup.isRestartNeeded()) {
+ throw new DiesOn(DeathType.FATAL).displaying("Error during Oomph operation: Need restart")
+ .ready();
+ }
+ }
+
+ /**
+ * @throws CoreException
+ */
+ private void cleanWorkspace() throws Die {
+ final IWorkspace workspace = org.eclipse.core.resources.ResourcesPlugin.getWorkspace();
+ try {
+ workspace.run(new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IWorkspaceRoot root = workspace.getRoot();
+ for (IProject project : root.getProjects()) {
+ project.delete(false, true, monitor);
+ }
+
+ for (File file : root.getLocation().toFile().listFiles()) {
+ if (file.isDirectory()) {
+ // Hack waiting for a response on
+ // https://www.eclipse.org/forums/index.php?t=rview&goto=1415112#msg_1415112
+ if (".metadata".equals(file.getName())) { //$NON-NLS-1$
+ // Deletes the Oomph import-history.properties to force new import
+ File importHistory = new File(
+ file.getAbsolutePath()
+ + SEP
+ + ".plugins/org.eclipse.oomph.setup.projects/import-history.properties"); //$NON-NLS-1$
+ if (importHistory.exists()) {
+ IOUtil.deleteBestEffort(importHistory);
+ try {
+ importHistory.createNewFile();
+ } catch (IOException e) {
+ throw new CoreException(
+ new Status(IStatus.ERROR, "org.eclipse.emf.compare.git.pgm",
+ "Unable to delete the file .plugins/org.eclipse.oomph.setup.projects/import-history.properties"));
+ }
+ }
+ }
+ }
+ }
+ }
+ }, null);
+ } catch (CoreException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+ }
+
+ /**
+ * Forces to wait for all EGit operation to terminate.
+ * <p>
+ * If this is not done then it might happen that some projects are not connected yet whereas the git
+ * command is being performed.
+ * </p>
+ *
+ * @throws InterruptedException
+ */
+ private void waitEgitJobs() throws InterruptedException {
+ IJobManager jobMan = Job.getJobManager();
+ jobMan.join(JobFamilies.AUTO_SHARE, new NullProgressMonitor());
+ jobMan.join(JobFamilies.AUTO_IGNORE, new NullProgressMonitor());
+ jobMan.join(JobFamilies.REPOSITORY_CHANGED, new NullProgressMonitor());
+ jobMan.join(JobFamilies.INDEX_DIFF_CACHE_UPDATE, new NullProgressMonitor());
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public Object start(IApplicationContext context) throws Exception {
+ // Prevents VM args if the application exits on something different that 0
+ System.setProperty(IApplicationContext.EXIT_DATA_PROPERTY, EMPTY_STRING);
+ final Map<?, ?> args = context.getArguments();
+ final String[] appArgs = (String[])args.get("application.args"); //$NON-NLS-1$
+
+ // This time it creates the repository using EGit code in order to add the repository to the EGit
+ // cache
+ final CmdLineParserRepositoryBuilder clp = CmdLineParserRepositoryBuilder
+ .newEGitRepoBuilderCmdParser(this);
+ try {
+ clp.parseArgument(appArgs);
+ repo = clp.getRepo();
+ } catch (CmdLineException err) {
+ err.printStackTrace();
+ System.err.println(err.getMessage());
+ dispose();
+ return Returns.ERROR;
+ }
+ try {
+ performStartup();
+ return performGitCommand();
+ } catch (Die e) {
+ Integer returnCode = EMFCompareGitPGMUtil.handleDieError(e, showStackTrace);
+ return returnCode;
+ } finally {
+ dispose();
+ }
+
+ }
+
+ protected void dispose() {
+ if (repo != null) {
+ repo.close();
+ }
+ progressPageLog.setTerminating();
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ public void stop() {
+ // Nothing to do.
+ }
+
+ /**
+ * @see org.eclipse.egit.ui.internal.CompareUtils#canDirectlyOpenInCompare(IFile)
+ * @param file
+ * the file to test.
+ * @return true if the file to test is EMFCompare compliant, false otherwise.
+ */
+ protected boolean isEMFCompareCompliantFile(RemoteResourceMappingContext mergeContext, IFile file) {
+ try {
+ EMFModelProvider modelProvider = new EMFModelProvider();
+ ResourceMapping[] modelMappings = modelProvider.getMappings(file, mergeContext,
+ new NullProgressMonitor());
+ if (modelMappings.length > 0) {
+ return true;
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets the tree iterator of the id located in the repository.
+ *
+ * @param repository
+ * the repository containing the id.
+ * @param id
+ * the id for which we want the tree iterator.
+ * @return the tree iterator of the id located in the repository.
+ * @throws IOException
+ */
+ protected AbstractTreeIterator getTreeIterator(Repository repository, ObjectId id) throws IOException {
+ final CanonicalTreeParser p = new CanonicalTreeParser();
+ final ObjectReader or = repository.newObjectReader();
+ try {
+ p.reset(or, new RevWalk(repository).parseTree(id));
+ return p;
+ } finally {
+ or.release();
+ }
+ }
+
+ /**
+ * Simulate a comparison between the two given references and returns back the subscriber that can provide
+ * all computed synchronization information.
+ *
+ * @param sourceRef
+ * Source reference (i.e. "left" side of the comparison).
+ * @param targetRef
+ * Target reference (i.e. "right" side of the comparison).
+ * @param comparedFile
+ * The file we are comparing (that would be the file right-clicked into the workspace).
+ * @return The created subscriber.
+ */
+ protected RemoteResourceMappingContext createSubscriberForComparison(Repository repository,
+ ObjectId sourceRef, ObjectId targetRef, IFile comparedFile) throws IOException {
+ final GitSynchronizeData data = new GitSynchronizeData(repository, sourceRef.getName(), targetRef
+ .getName(), false);
+ final GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+ GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(dataSet);
+ subscriber.init(new NullProgressMonitor());
+ return new GitSubscriberResourceMappingContext(subscriber, dataSet);
+ }
+
+ /**
+ * This will query all model providers for those that are enabled on the given file and list all mappings
+ * available for that file.
+ *
+ * @param file
+ * The file for which we need the associated resource mappings.
+ * @return All mappings available for that file.
+ */
+ protected ResourceMapping[] getResourceMappings(RemoteResourceMappingContext mergeContext, IFile file) {
+ final Set<ResourceMapping> mappings = new LinkedHashSet<ResourceMapping>();
+ try {
+ EMFModelProvider modelProvider = new EMFModelProvider();
+ ResourceMapping[] modelMappings = modelProvider.getMappings(file, mergeContext,
+ new NullProgressMonitor());
+ for (ResourceMapping mapping : modelMappings) {
+ mappings.add(mapping);
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ return mappings.toArray(new ResourceMapping[mappings.size()]);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalDiffApplication.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalDiffApplication.java
new file mode 100644
index 0000000..56cb1e5
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalDiffApplication.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.app;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.BasicMonitor;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.args.PathFilterHandler;
+import org.eclipse.emf.compare.git.pgm.internal.args.RefOptionHandler;
+import org.eclipse.emf.compare.ide.ui.internal.logical.ComparisonScopeBuilder;
+import org.eclipse.emf.compare.ide.ui.internal.logical.EMFResourceMapping;
+import org.eclipse.emf.compare.ide.ui.internal.logical.IdenticalResourceMinimizer;
+import org.eclipse.emf.compare.ide.ui.logical.IModelMinimizer;
+import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.jgit.api.DiffCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+/**
+ * Logical diff application. <h3>Name</h3>
+ * <p>
+ * logicaldiff - Git Logical Diff
+ * </p>
+ * <h4>Synopsis</h4>
+ * <p>
+ * logicaldiff <setup> <commit> [<compareWithCommit>] [ -- <paths...>]
+ * </p>
+ * <h4>Description</h4>
+ * <p>
+ * The logical diff is used to display differences using logical model.
+ * </p>
+ * </p>
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+@SuppressWarnings({"restriction" })
+public class LogicalDiffApplication extends AbstractLogicalApplication {
+
+ /**
+ * Holds the reference from which the differences should be displayed.
+ */
+ @Argument(index = 2, multiValued = false, required = true, metaVar = "<commit>", usage = "Commit ID or branch name.", handler = RefOptionHandler.class)
+ private ObjectId commit;
+
+ /**
+ * Optional reference used to view the differences between {@link #commit} and {@link #commitWith}.
+ */
+ @Argument(index = 3, multiValued = false, required = false, metaVar = "<compareWithCommit>", usage = "Commit ID or branch name. This is to view the changes between <commit> and <compareWithCommit> or HEAD if not specified.", handler = RefOptionHandler.class)
+ private ObjectId commitWith;
+
+ /**
+ * {@link TreeFilter} use to filter file on which differences should be shown.
+ */
+ @Option(name = "--", metaVar = "<path...>", multiValued = false, handler = PathFilterHandler.class, usage = "This is used to limit the diff to the named paths (you can give directory names and get diff for all files under them).")
+ private TreeFilter pathFilter;
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ protected Integer performGitCommand() {
+ try {
+ IWorkspace ws = ResourcesPlugin.getWorkspace();
+
+ // Call JGit diff to get the files involved
+ OutputStream out = new ByteArrayOutputStream();
+ DiffCommand diffCommand = Git.open(repo.getDirectory()).diff().setOutputStream(out);
+ if (commit != null) {
+ diffCommand = diffCommand.setOldTree(getTreeIterator(repo, commit));
+ }
+ if (commitWith != null) {
+ diffCommand = diffCommand.setNewTree(getTreeIterator(repo, commitWith));
+ }
+ if (pathFilter != null) {
+ diffCommand = diffCommand.setPathFilter(pathFilter);
+ }
+ Set<IFile> files = new HashSet<IFile>();
+ List<DiffEntry> entries = diffCommand.call();
+
+ for (DiffEntry diffEntry : entries) {
+ String path = diffEntry.getOldPath();
+ if (path != null) {
+ IFile file = ws.getRoot().getFile(new Path(path));
+ if (file != null) {
+ files.add(file);
+ }
+ }
+ }
+
+ if (files.isEmpty()) {
+ System.out.println("No difference to display.");
+ return Returns.COMPLETE.code();
+ }
+
+ for (IFile file : files) {
+ RemoteResourceMappingContext mergeContext = createSubscriberForComparison(repo, commit,
+ commitWith, file);
+ if (!isEMFCompareCompliantFile(mergeContext, file)) {
+ diffCommand.setPathFilter(PathFilter.create(file.getProjectRelativePath().toString()));
+ diffCommand.call();
+ System.out.println(out.toString());
+ } else {
+ final ResourceMapping[] emfMappings = getResourceMappings(mergeContext, file);
+ for (ResourceMapping mapping : emfMappings) {
+ if (mapping instanceof EMFResourceMapping) {
+ /*
+ * These two won't be used by the builder in our case since we retrieve the
+ * already created syncModel from the resource mapping.
+ */
+ final IModelMinimizer minimizer = new IdenticalResourceMinimizer();
+ final NullProgressMonitor nullProgressMonitor = new NullProgressMonitor();
+
+ mapping.getTraversals(mergeContext, nullProgressMonitor);
+ final SynchronizationModel syncModel = ((EMFResourceMapping)mapping)
+ .getLatestModel();
+ minimizer.minimize(syncModel, nullProgressMonitor);
+ final IComparisonScope scope = ComparisonScopeBuilder.create(syncModel,
+ nullProgressMonitor);
+
+ final Comparison comparison = EMFCompare.builder().build().compare(scope,
+ BasicMonitor.toMonitor(nullProgressMonitor));
+
+ Resource resource = new XMIResourceImpl();
+ Copier copier = new Copier(false);
+ EObject comparisonCopy = copier.copy(comparison);
+ copier.copyReferences();
+ resource.getContents().add(comparisonCopy);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ resource.save(baos, null);
+ System.out.println(baos.toString("UTF-8"));//$NON-NLS-1$
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace();
+ }
+
+ return Returns.COMPLETE.code();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalMergeApplication.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalMergeApplication.java
new file mode 100644
index 0000000..c8159e2
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/app/LogicalMergeApplication.java
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.app;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.op.MergeOperation;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.args.RefOptionHandler;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.MergeResult;
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.merge.MergeStrategy;
+import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+/**
+ * Logical merge application. <h3>Name</h3>
+ * <p>
+ * logicalmerge - Git Logical Merge
+ * </p>
+ * <h4>Synopsis</h4>
+ * <p>
+ * logicalmerge <setup> <commit>
+ * </p>
+ * <h4>Description</h4>
+ * <p>
+ * The logical merge command is used to merge logical models. Instead of merging each file one by one like git
+ * would do, it uses a set of semantically interconnected files. It avoids semantical breakage of models.
+ * </p>
+ * </p>
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+@SuppressWarnings({"restriction" })
+public class LogicalMergeApplication extends AbstractLogicalApplication {
+
+ /**
+ * Length of a short commit id.
+ */
+ private static final int SHORT_COMMIT_ID_LENGTH = 7;
+
+ /**
+ * Holds a ObjectId that need to be merged.
+ */
+ @Argument(index = 2, required = true, metaVar = "<commit>", usage = "Commit ID or branch name to merge.", handler = RefOptionHandler.class)
+ private ObjectId commit;
+
+ /**
+ * Optional message used for the merge commit.
+ */
+ @Option(name = "-m", metaVar = "message", required = false, usage = " Set the commit message to be used for the merge commit (in case one is created).")
+ private String message;
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ protected Integer performGitCommand() throws Die {
+
+ try {
+ MergeOperation merge = new MergeOperation(repo, commit.getName());
+ if (message != null) {
+ merge.setMessage(message);
+ }
+ merge.execute(new NullProgressMonitor());
+ MergeResult result = merge.getResult();
+ Ref oldHead = repo.getRef(Constants.HEAD);
+
+ return handleResult(result, oldHead, MergeStrategy.RECURSIVE);
+ } catch (Exception e) {
+ progressPageLog.log(e);
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ }
+
+ /**
+ * Handles the merge result. This method return the {@link Returns} depending of the merge status and
+ * display a message to the user.
+ *
+ * @param mergeResult
+ * The result of the merge.
+ * @param oldHead
+ * the old HEAD reference before merge.
+ * @param strategy
+ * The strategy used for the merge.
+ * @return a {@link Returns}.
+ * @throws Die
+ * if the merge ends on error.
+ * @throws IOException
+ * if a problem occurs while displaying a message to the user.
+ */
+ private Integer handleResult(MergeResult mergeResult, Ref oldHead, MergeStrategy strategy) throws Die,
+ IOException {
+ final Integer returnCode;
+ final String messageToPrint;
+ switch (mergeResult.getMergeStatus()) {
+ case MERGED:
+ messageToPrint = new StringBuilder().append("Merge made by '").append(strategy.getName())
+ .append("' strategy.").append(EOL).toString();
+ returnCode = Returns.COMPLETE.code();
+ break;
+ case ALREADY_UP_TO_DATE:
+ messageToPrint = new StringBuilder().append("Already up to date.").append(EOL).toString();
+ returnCode = Returns.COMPLETE.code();
+ break;
+ case FAST_FORWARD:
+ messageToPrint = buildFastForwardMessage(mergeResult, oldHead);
+ returnCode = Returns.COMPLETE.code();
+ break;
+ case CONFLICTING:
+ returnCode = Returns.ABORTED.code();
+ messageToPrint = buildConflictingMessage(mergeResult);
+ break;
+ case FAILED:
+ throw new DiesOn(DeathType.ERROR).displaying(getFailedMessage(mergeResult)).ready();
+ case ABORTED:
+ throw new DiesOn(DeathType.ERROR).displaying("There is no merge to abort").ready();
+ case NOT_SUPPORTED:
+ case MERGED_NOT_COMMITTED:
+ case CHECKOUT_CONFLICT:
+ case MERGED_SQUASHED:
+ case FAST_FORWARD_SQUASHED:
+ case MERGED_SQUASHED_NOT_COMMITTED:
+ default:
+ throw new DiesOn(DeathType.SOFTWARE_ERROR).displaying(getDefaultErrorMessage(mergeResult))
+ .ready();
+ }
+ System.out.println(messageToPrint);
+ return returnCode;
+
+ }
+
+ /**
+ * Builds the message to display to the user when the merge ends on a FAST_FORWARD state.
+ *
+ * @param mergeResult
+ * The merge result.
+ * @param oldHead
+ * The previous head before merge.
+ * @return a message.
+ */
+ private String buildFastForwardMessage(MergeResult mergeResult, Ref oldHead) {
+ final StringBuilder messageBuilder = new StringBuilder();
+ ObjectId oldHeadId = oldHead.getObjectId();
+ messageBuilder.append("Updating ").append(oldHeadId.abbreviate(SHORT_COMMIT_ID_LENGTH).name())
+ .append("..").append(mergeResult.getNewHead().abbreviate(SHORT_COMMIT_ID_LENGTH).name())
+ .append(EOL);
+ messageBuilder.append(mergeResult.getMergeStatus().toString());
+ return messageBuilder.toString();
+ }
+
+ /**
+ * Builds the message to display to the user when merge ends on a conflicting state.
+ *
+ * @param mergeResult
+ * {@link MergeResult}.
+ * @return a message.
+ */
+ private String buildConflictingMessage(MergeResult mergeResult) {
+ final StringBuilder messageBuildder = new StringBuilder();
+ try {
+ // Should use mergeResult.getConflicting() however due to its random result we prefer using the
+ // status of the git repository.
+ final Status status = Git.wrap(repo).status().call();
+ List<String> conflictingFile = Lists.newArrayList(status.getConflicting());
+ // In order to have a determinist order.
+ Collections.sort(conflictingFile);
+ for (String conflicting : conflictingFile) {
+ messageBuildder.append("Auto-merging failed in ").append(conflicting).append(EOL);
+
+ }
+ } catch (NoWorkTreeException e) {
+ // Does nothing since this for console message
+ } catch (GitAPIException e) {
+ // Does nothing since this for console message
+ }
+ messageBuildder.append("Automatic merge failed; fix conflicts and then commit the result.").append(
+ EOL);
+
+ return messageBuildder.toString();
+ }
+
+ /**
+ * Builds the message to display to the user when the merge ends on a FAILED status.
+ *
+ * @param mergeResult
+ * The merge result.
+ * @return a message.
+ */
+ private String getFailedMessage(MergeResult mergeResult) {
+ final StringBuilder errorMessage = new StringBuilder();
+ List<String> dirtyFiles = Lists.newArrayList();
+ List<String> notDeletedFiles = Lists.newArrayList();
+ for (Entry<String, MergeFailureReason> mergeFailure : mergeResult.getFailingPaths().entrySet()) {
+
+ switch (mergeFailure.getValue()) {
+ case DIRTY_INDEX:
+ case DIRTY_WORKTREE:
+ dirtyFiles.add(mergeFailure.getKey());
+ break;
+ case COULD_NOT_DELETE:
+ notDeletedFiles.add(mergeFailure.getKey());
+ break;
+ default:
+ break;
+ }
+ }
+ if (!dirtyFiles.isEmpty()) {
+ errorMessage.append("Your local changes to the following files would be overwritten by merge:"
+ + EOL);
+ errorMessage.append(Joiner.on(EOL).join(dirtyFiles));
+ errorMessage.append("Please, commit your changes or stash them before you can merge.");
+ }
+ if (!notDeletedFiles.isEmpty()) {
+ errorMessage.append("Could not delete following files:" + EOL);
+ errorMessage.append(Joiner.on(EOL).join(notDeletedFiles));
+ }
+ errorMessage.append("Aborting." + EOL);
+ return errorMessage.toString();
+ }
+
+ /**
+ * Gets the default message error.
+ *
+ * @param mergeResult
+ * {@link MergeResult}.
+ * @return An error message.
+ */
+ private String getDefaultErrorMessage(MergeResult mergeResult) {
+ return new StringBuilder().append("Unsupported merge status '").append(
+ mergeResult.getMergeStatus().toString()).append("'").append(EOL).toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/CmdLineParserRepositoryBuilder.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/CmdLineParserRepositoryBuilder.java
new file mode 100644
index 0000000..7222b76
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/CmdLineParserRepositoryBuilder.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.args;
+
+import static org.eclipse.emf.compare.git.pgm.internal.Messages.CAN_T_FIND_GIT_REPOSITORY_MESSAGE;
+import static org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType.FATAL;
+
+import com.google.common.base.Preconditions;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.egit.core.RepositoryCache;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryBuilder;
+import org.kohsuke.args4j.CmdLineParser;
+
+/**
+ * CmdLineParser that is aware of a git repository. Some {@link org.kohsuke.args4j.spi.OptionHandler}s might
+ * need it for validation.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class CmdLineParserRepositoryBuilder extends CmdLineParser {
+
+ /**
+ * Functional interface used to build a {@link Repository}.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+ public interface RepoBuilder {
+
+ Repository buildRepository(String gitDir) throws Die;
+ }
+
+ /**
+ * {@link Repository} builder that uses pure JGit code.
+ */
+ private static RepoBuilder JGIT_REPO_BUILDER = new RepoBuilder() {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.internal.args.CmdLineParserRepositoryBuilder.RepoBuilder#buildRepository(java.lang.String)
+ */
+ public Repository buildRepository(String aGitdir) throws Die {
+ final File gitDir;
+ if (aGitdir == null) {
+ gitDir = null;
+ } else {
+ gitDir = new File(aGitdir);
+ }
+ RepositoryBuilder rb = new RepositoryBuilder().setGitDir(gitDir).readEnvironment().setMustExist(
+ true).findGitDir();
+ if (rb.getGitDir() == null) {
+ throw new DiesOn(FATAL).displaying(CAN_T_FIND_GIT_REPOSITORY_MESSAGE).ready();
+ }
+ Repository repo;
+ try {
+ repo = rb.build();
+ } catch (RepositoryNotFoundException e) {
+ throw new DiesOn(FATAL).displaying(CAN_T_FIND_GIT_REPOSITORY_MESSAGE).ready();
+ } catch (IOException e) {
+ throw new DiesOn(FATAL).duedTo(e).displaying("Cannot build the git repository").ready();
+ }
+ return repo;
+ }
+
+ };
+
+ /**
+ * {@link Repository} builder that uses pure EGit code.
+ * <p>
+ * This builder creates the repository and add it the {@link RepositoryCache} of EGit
+ * </p>
+ */
+ private static RepoBuilder EGIT_REPO_BUILDER = new RepoBuilder() {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.internal.args.CmdLineParserRepositoryBuilder.RepoBuilder#buildRepository(java.lang.String)
+ */
+ public Repository buildRepository(String aGitdir) throws Die {
+ Preconditions.checkNotNull(aGitdir);
+ File gitDir = new File(aGitdir);
+ if (!gitDir.exists()) {
+ throw new DiesOn(DeathType.FATAL).displaying(
+ "Can not build git reposutory: " + aGitdir + "does not exist").ready();
+ }
+
+ try {
+ Repository repository = org.eclipse.egit.core.Activator.getDefault().getRepositoryCache()
+ .lookupRepository(gitDir);
+ if (repository == null) {
+ throw new DiesOn(DeathType.FATAL).displaying("Can build repository " + aGitdir).ready();
+ }
+ return repository;
+ } catch (IOException e1) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e1).displaying("Can build repository " + aGitdir)
+ .ready();
+ }
+ }
+
+ };
+
+ /**
+ * Git directory.
+ */
+ private String gitDir = null;
+
+ /**
+ * Git repository.
+ */
+ private Repository repo = null;
+
+ /**
+ * {@link Repository} builder.
+ */
+ private final RepoBuilder builder;
+
+ /**
+ * Creates a new {@link CmdLineParser} that will build the {@link Repository} using pure JGit methods.
+ * <p>
+ * Using this method calling {@link #setGitDir(String)} is optional.
+ * </p>
+ *
+ * @param bean
+ * @return
+ */
+ public static CmdLineParserRepositoryBuilder newJGitRepoBuilderCmdParser(Object bean) {
+ return new CmdLineParserRepositoryBuilder(bean, JGIT_REPO_BUILDER);
+ }
+
+ /**
+ * Creates a new {@link CmdLineParser} that will build the {@link Repository} using EGit methods (creates
+ * the repository and add it to the cache).
+ * <p>
+ * With this implementation the method {@link #setGitDir(String)} needs to be called before the
+ * {@link #getRepo()} since EGit needs the path to the git dir to build the repository
+ * </p>
+ *
+ * @param bean
+ * @return
+ */
+ public static CmdLineParserRepositoryBuilder newEGitRepoBuilderCmdParser(Object bean) {
+ return new CmdLineParserRepositoryBuilder(bean, EGIT_REPO_BUILDER);
+ }
+
+ /**
+ * Constructor.
+ * <p>
+ * The git repository will be buit during argument parsing
+ * </p>
+ *
+ * @param bean
+ */
+ private CmdLineParserRepositoryBuilder(Object bean, RepoBuilder builder) {
+ super(bean);
+ this.builder = builder;
+ }
+
+ /**
+ * Get the git {@link Repository}.
+ * <p>
+ * The first time this method is called it may build the repository and so laucn a {@link Die} exception
+ * <p>
+ *
+ * @return
+ * @throws Die
+ */
+ public Repository getRepo() throws Die {
+ if (repo == null) {
+ repo = builder.buildRepository(gitDir);
+ }
+ return repo;
+ }
+
+ /**
+ * Sets the path to the git dir repository.
+ * <p>
+ * This method does not need to be called if the command has been run inside the git repository. However
+ * if it's used it needs to be called before the first call of the {@link #getRepo()} method.
+ * </p>
+ *
+ * @param gitDir
+ */
+ public void setGitDir(String gitDir) {
+ // The gitDir argument should be provided before the repository is built
+ Preconditions.checkArgument(repo == null);
+ this.gitDir = gitDir;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/GitDirHandler.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/GitDirHandler.java
new file mode 100644
index 0000000..9dd70e6
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/GitDirHandler.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.args;
+
+import com.google.common.base.Preconditions;
+
+import org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+import org.kohsuke.args4j.spi.StringOptionHandler;
+
+/**
+ * OptionHandler that parses a git directory from a command line and set the gitdir value of the
+ * CmdLineParserRepositoryBuilder.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class GitDirHandler extends StringOptionHandler {
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * {@link OptionHandler#owner}
+ * @param option
+ * {@link OptionHandler#option}
+ * @param setter
+ * {@link OptionHandler#setter}
+ */
+ public GitDirHandler(CmdLineParser parser, OptionDef option, Setter<? super String> setter) {
+ super(parser, option, setter);
+ Preconditions.checkArgument(parser instanceof CmdLineParserRepositoryBuilder);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.kohsuke.args4j.spi.OptionHandler#parseArguments(org.kohsuke.args4j.spi.Parameters)
+ */
+ @Override
+ public int parseArguments(Parameters params) throws CmdLineException {
+ String dir = params.getParameter(0);
+ String absoluteDir = EMFCompareGitPGMUtil.toFileWithAbsolutePath(dir).toString();
+ ((CmdLineParserRepositoryBuilder)owner).setGitDir(absoluteDir);
+ return 1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.kohsuke.args4j.spi.OptionHandler#getDefaultMetaVariable()
+ */
+ @Override
+ public String getDefaultMetaVariable() {
+ return "gitdir"; //$NON-NLS-1$
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/LogicalCommandHandler.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/LogicalCommandHandler.java
new file mode 100644
index 0000000..fa666ea
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/LogicalCommandHandler.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.args;
+
+import org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommand;
+import org.eclipse.emf.compare.git.pgm.internal.cmd.CommandFactory;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+/**
+ * {@link OptionHandler} used to parse logical commands.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class LogicalCommandHandler extends OptionHandler<AbstractLogicalCommand> {
+
+ /**
+ * Meta var used to display the print usage message of the command.
+ */
+ private static final String CMD_META_VAR = "cmd"; //$NON-NLS-1$
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * {@link OptionHandler#owner}
+ * @param option
+ * {@link OptionHandler#option}
+ * @param setter
+ * {@link OptionHandler#setter}
+ */
+ public LogicalCommandHandler(CmdLineParser parser, OptionDef option,
+ Setter<? super AbstractLogicalCommand> setter) {
+ super(parser, option, setter);
+ }
+
+ @Override
+ public int parseArguments(final Parameters params) throws CmdLineException {
+
+ final String name = params.getParameter(0);
+ // Do not parse other argument since they will be parsed by subcommands.
+ owner.stopOptionParsing();
+ AbstractLogicalCommand cmd = CommandFactory.getInstance().createCommand(name);
+ if (cmd != null) {
+ setter.addValue(cmd);
+ } else {
+ throw new CmdLineException(owner, "Not a logical command " + name);
+ }
+ return 1;
+ }
+
+ @Override
+ public String getDefaultMetaVariable() {
+ return CMD_META_VAR;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/PathFilterHandler.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/PathFilterHandler.java
new file mode 100644
index 0000000..24234da
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/PathFilterHandler.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.args;
+
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+/**
+ * Consumes all arguments left and handles them as they were path.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class PathFilterHandler extends OptionHandler<PathFilter> {
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * {@link OptionHandler#owner}
+ * @param option
+ * {@link OptionHandler#option}
+ * @param setter
+ * {@link OptionHandler#setter}
+ */
+ public PathFilterHandler(CmdLineParser parser, OptionDef option, Setter<? super PathFilter> setter) {
+ super(parser, option, setter);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.kohsuke.args4j.spi.OptionHandler#parseArguments(org.kohsuke.args4j.spi.Parameters)
+ */
+ @Override
+ public int parseArguments(Parameters params) throws CmdLineException {
+ String path = params.getParameter(0);
+ setter.addValue(PathFilter.create(path));
+ return 1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.kohsuke.args4j.spi.OptionHandler#getDefaultMetaVariable()
+ */
+ @Override
+ public String getDefaultMetaVariable() {
+ return "<path...>";
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/RefOptionHandler.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/RefOptionHandler.java
new file mode 100644
index 0000000..2a35013
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/RefOptionHandler.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.args;
+
+import com.google.common.base.Preconditions;
+
+import org.eclipse.emf.compare.git.pgm.internal.exception.ArgumentValidationError;
+import org.eclipse.jgit.lib.ObjectId;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+/**
+ * OptionHandler that parses a commit reference from a command line and checks that it can be resolved in the
+ * git repository of the logical command.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class RefOptionHandler extends OptionHandler<ObjectId> {
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * {@link OptionHandler#owner}
+ * @param option
+ * {@link OptionHandler#option}
+ * @param setter
+ * {@link OptionHandler#setter}
+ */
+ public RefOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super ObjectId> setter) {
+ super(parser, option, setter);
+ Preconditions.checkArgument(parser instanceof CmdLineParserRepositoryBuilder);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.kohsuke.args4j.spi.OptionHandler#parseArguments(org.kohsuke.args4j.spi.Parameters)
+ */
+ @Override
+ public int parseArguments(Parameters params) throws CmdLineException {
+ String ref = params.getParameter(0);
+
+ ObjectId objectID;
+ try {
+ objectID = ((CmdLineParserRepositoryBuilder)owner).getRepo().resolve(ref);
+ setter.addValue(objectID);
+ } catch (Exception e) {
+ throw new ArgumentValidationError(owner, e);
+ }
+ if (objectID == null) {
+ throw new ArgumentValidationError(owner, ref + " - not a valid git reference.");
+ }
+ return 1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.kohsuke.args4j.spi.OptionHandler#getDefaultMetaVariable()
+ */
+ @Override
+ public String getDefaultMetaVariable() {
+ return "commit"; //$NON-NLS-1$
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/SetupFileOptionHandler.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/SetupFileOptionHandler.java
new file mode 100644
index 0000000..e2d43ee
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/args/SetupFileOptionHandler.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.args;
+
+import java.io.File;
+
+import org.eclipse.emf.compare.git.pgm.internal.exception.ArgumentValidationError;
+import org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.FileOptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+/**
+ * {@link FileOptionHandler} used to parse the setup argument.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+// TODO: Load the Oomph configuration here
+public class SetupFileOptionHandler extends FileOptionHandler {
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * {@link org.kohsuke.args4j.spi.OptionHandler.OptionHandler#owner}
+ * @param option
+ * {@link org.kohsuke.args4j.spi.OptionHandler.OptionHandler#option}
+ * @param setter
+ * {@link org.kohsuke.args4j.spi.OptionHandler.OptionHandler#setter}
+ */
+ public SetupFileOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super File> setter) {
+ super(parser, option, setter);
+ }
+
+ @Override
+ public int parseArguments(Parameters params) throws CmdLineException {
+ File setupFile = EMFCompareGitPGMUtil.toFileWithAbsolutePath(params.getParameter(0));
+ if (!setupFile.exists()) {
+ throw new ArgumentValidationError(owner, setupFile + " setup file does not exist");
+ }
+ setter.addValue(setupFile);
+ return 1;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/AbstractLogicalCommand.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/AbstractLogicalCommand.java
new file mode 100644
index 0000000..82b0109
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/AbstractLogicalCommand.java
@@ -0,0 +1,785 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.Options.GIT_DIR_OPT;
+import static org.eclipse.emf.compare.git.pgm.internal.Options.HELP_OPT;
+import static org.eclipse.emf.compare.git.pgm.internal.Options.SHOW_STACK_TRACE_OPT;
+import static org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType.FATAL;
+import static org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType.SOFTWARE_ERROR;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.SEP;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.toFileWithAbsolutePath;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.util.Collection;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.ProgressPageLog;
+import org.eclipse.emf.compare.git.pgm.internal.args.CmdLineParserRepositoryBuilder;
+import org.eclipse.emf.compare.git.pgm.internal.args.GitDirHandler;
+import org.eclipse.emf.compare.git.pgm.internal.args.SetupFileOptionHandler;
+import org.eclipse.emf.compare.git.pgm.internal.exception.ArgumentValidationError;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.equinox.p2.metadata.ILicense;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.util.io.ThrowingPrintWriter;
+import org.eclipse.oomph.base.provider.BaseEditUtil;
+import org.eclipse.oomph.internal.setup.SetupPrompter;
+import org.eclipse.oomph.setup.Index;
+import org.eclipse.oomph.setup.InstallationTask;
+import org.eclipse.oomph.setup.Product;
+import org.eclipse.oomph.setup.ProductCatalog;
+import org.eclipse.oomph.setup.ProductVersion;
+import org.eclipse.oomph.setup.Project;
+import org.eclipse.oomph.setup.ProjectCatalog;
+import org.eclipse.oomph.setup.SetupFactory;
+import org.eclipse.oomph.setup.SetupPackage;
+import org.eclipse.oomph.setup.SetupTask;
+import org.eclipse.oomph.setup.Trigger;
+import org.eclipse.oomph.setup.WorkspaceTask;
+import org.eclipse.oomph.setup.internal.core.SetupContext;
+import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer;
+import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
+import org.eclipse.oomph.setup.internal.core.util.SetupUtil;
+import org.eclipse.oomph.setup.log.ProgressLog;
+import org.eclipse.oomph.setup.p2.P2Task;
+import org.eclipse.oomph.util.Confirmer;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.Option;
+
+/**
+ * Abstract class for any logical command.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("restriction")
+public abstract class AbstractLogicalCommand {
+
+ protected static final String PROP_SETUP_CONFIRM_SKIP = "oomph.setup.confirm.skip"; //$NON-NLS-1$
+
+ protected static final String PROP_SETUP_OFFLINE_STARTUP = "oomph.setup.offline.startup"; //$NON-NLS-1$
+
+ protected static final String PROP_SETUP_MIRRORS_STARTUP = "oomph.setup.mirrors.startup"; //$NON-NLS-1$
+
+ /**
+ * Holds true if a user has set the help option to true.
+ */
+ @Option(name = HELP_OPT, usage = "Dispays help for this command.", aliases = {"-h" })
+ private boolean help;
+
+ /**
+ * Holds the Oomph model setup file.
+ */
+ @Argument(index = 0, metaVar = "<setup>", required = true, usage = "Path to the setup file. The setup file is a Oomph model.", handler = SetupFileOptionHandler.class)
+ private File setupFile;
+
+ /**
+ * Holds true if the java stack trace should be displayed in the console if any.
+ */
+ @Option(name = SHOW_STACK_TRACE_OPT, usage = "Use this option to display java stack trace in console on error.")
+ private boolean showStackTrace;
+
+ /**
+ * Holds git directory location.
+ */
+ @Option(name = GIT_DIR_OPT, metaVar = "gitFolderPath", usage = "Path to the .git folder of your repository.", handler = GitDirHandler.class)
+ private String gitdir;
+
+ /**
+ * Name of this command.
+ */
+ private String commandName;
+
+ /**
+ * Writer to output to, typically this is standard output.
+ */
+ private ThrowingPrintWriter out;
+
+ /**
+ * Usage of this command. This field is filled only if the help parameter has been provided.
+ */
+ private String usage;
+
+ /**
+ * Git repository for this command to be executed in.
+ */
+ private Repository repo;
+
+ /**
+ * SetupTaskPerformer of this command.
+ */
+ private SetupTaskPerformer performer;
+
+ private ProgressLog progressPageLog;
+
+ /**
+ * Constructor.
+ */
+ protected AbstractLogicalCommand() {
+ // Force the command to be built in the CommandFactory.
+ }
+
+ /**
+ * Sets the command name.
+ *
+ * @param name
+ * the command name.
+ */
+ final void setCommandName(final String name) {
+ commandName = name;
+ }
+
+ /**
+ * Executes the command.
+ *
+ * @return The {@link Returns} for this command.
+ * @throws Die
+ * if the program stop prematurely.
+ * @throws IOException
+ * propagation.
+ */
+ public final Integer execute() throws Die, IOException {
+ if (!help) {
+ return internalRun();
+ } else {
+ out.print(usage);
+ }
+ return Returns.COMPLETE.code();
+ }
+
+ /**
+ * Gets the git repository.
+ *
+ * @return the repository this command uses.
+ */
+ protected Repository getRepository() {
+ return repo;
+ }
+
+ /**
+ * Gets the SetupTaskPerformer.
+ *
+ * @return
+ */
+ protected SetupTaskPerformer getPerformer() {
+ return performer;
+ }
+
+ /**
+ * Parses the arguments related to this command. It also in charge of building the git repository.
+ * <p>
+ * Since the --git-dir option can be passed throught the command line, the parser is also in charge of
+ * building the repository
+ * </p>
+ *
+ * @param args
+ * arguments.
+ * @throws Die
+ * if the program exits prematurely.
+ */
+ protected Repository parseArgumentsAndBuildRepo(Collection<String> args) throws Die {
+ final CmdLineParserRepositoryBuilder clp = CmdLineParserRepositoryBuilder
+ .newJGitRepoBuilderCmdParser(this);
+ try {
+ clp.parseArgument(args);
+ } catch (ArgumentValidationError err) {
+ // Only throw an error if the user has not required help.
+ if (!help) {
+ if (err.getCause() instanceof Die) {
+ // Do not wrap a Die exception
+ throw (Die)err.getCause();
+ } else {
+ throw new DiesOn(FATAL).displaying(err.getMessage()).ready();
+ }
+ }
+ } catch (CmdLineException err) {
+ // Only throw an error if the user has not required help.
+ if (!help) {
+ ByteArrayOutputStream localOut = new ByteArrayOutputStream();
+ PrintWriter printWritter = new PrintWriter(localOut);
+ printUsage(err.getMessage() + " in:" + EOL, clp, printWritter);
+ printWritter.close();
+ throw new DiesOn(FATAL).displaying(localOut.toString()).ready();
+ }
+ }
+
+ if (help) {
+ // The user has used the help option. Saves the usage message for later
+ ByteArrayOutputStream localOut = new ByteArrayOutputStream();
+ PrintWriter printWritter = new PrintWriter(localOut);
+ printUsage("", clp, printWritter);
+ printWritter.close();
+ usage = localOut.toString();
+ }
+ return clp.getRepo();
+ }
+
+ /**
+ * Prints the usage of this command.
+ *
+ * @param message
+ * a prefix message.
+ * @param clp
+ * the current command line parser.
+ * @param printWritter
+ * A {@link PrintWriter}.
+ */
+ protected void printUsage(final String message, final CmdLineParser clp, PrintWriter printWritter) {
+ printWritter.println(message);
+ printWritter.print(commandName);
+ clp.printSingleLineUsage(printWritter, null);
+ printWritter.println();
+ printWritter.println();
+
+ clp.printUsage(printWritter, null);
+ printWritter.println();
+
+ printWritter.flush();
+ }
+
+ /**
+ * Returns the printer to write message in console.
+ *
+ * @return {@link ThrowingPrintWriter}
+ */
+ protected ThrowingPrintWriter out() {
+ return out;
+ }
+
+ /**
+ * Runs the command.
+ *
+ * @return Return code.
+ * @throws Exception
+ * exception on error.
+ */
+ protected abstract Integer internalRun() throws Die, IOException;
+
+ public boolean isShowStackTrace() {
+ return showStackTrace;
+ }
+
+ /**
+ * Builds this command.
+ *
+ * @param args
+ * The arguments for this command.
+ * @param environmentSetupURI
+ * URI to the environment setup file.
+ * @throws Die
+ * exception on error.
+ * @throws IOException
+ */
+ public void build(Collection<String> args, URI environmentSetupURI) throws Die, IOException {
+
+ repo = parseArgumentsAndBuildRepo(args);
+
+ try {
+ final String outputEncoding;
+ if (repo != null) {
+ outputEncoding = repo.getConfig().getString("i18n", null, "logOutputEncoding"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ outputEncoding = null;
+ }
+ BufferedWriter outbufw;
+ if (outputEncoding != null) {
+ outbufw = new BufferedWriter(new OutputStreamWriter(System.out, outputEncoding));
+ } else {
+ outbufw = new BufferedWriter(new OutputStreamWriter(System.out));
+ }
+ out = new ThrowingPrintWriter(outbufw);
+ } catch (IOException e) {
+ throw new DiesOn(SOFTWARE_ERROR).displaying("Cannot create input stream").ready();
+ }
+
+ if (!help) {
+ try {
+ // Loads eclipse environment setup model.
+ performer = createSetupTaskPerformer(setupFile.getAbsolutePath(), environmentSetupURI);
+ performer.perform();
+
+ if (!performer.hasSuccessfullyPerformed()) {
+ throw new DiesOn(DeathType.FATAL).displaying("Error durring Oomph operation").ready();
+ }
+ } catch (Die e) {
+ throw e;
+ } catch (Exception e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+ }
+
+ }
+
+ /**
+ * Create and configure the setup task performer to provision the eclipse environment.
+ *
+ * @param userSetupFilePath
+ * the path of the user setup model.
+ * @return a SetupTaskPerformer.
+ * @throws Die
+ * @throws IOException
+ * @throws Exception
+ */
+ private SetupTaskPerformer createSetupTaskPerformer(String userSetupFilePath, URI environmentSetupURI)
+ throws IOException, Die {
+ // Load user setup model.
+ ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(BaseEditUtil
+ .createAdapterFactory());
+
+ ResourceSet rs = SetupUtil.createResourceSet();
+ rs.eAdapters().add(
+ new AdapterFactoryEditingDomain.EditingDomainProvider(new AdapterFactoryEditingDomain(
+ adapterFactory, null, rs)));
+ rs.getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING,
+ ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
+
+ URI startupSetupURI = URI.createFileURI(userSetupFilePath);
+ Resource startupSetup = null;
+ try {
+ startupSetup = rs.getResource(startupSetupURI, true);
+ } catch (Exception e) {
+ // Does nothing handle later
+ }
+ if (startupSetup == null) {
+ throw new DiesOn(FATAL).displaying(userSetupFilePath + " is not a valid setup file").ready();
+ }
+
+ Index startupSetupIndex = (Index)EcoreUtil.getObjectByType(startupSetup.getContents(),
+ SetupPackage.Literals.INDEX);
+
+ if (startupSetupIndex == null) {
+ throw new DiesOn(SOFTWARE_ERROR).displaying("The index of of the setup file should not be null")
+ .ready();
+ }
+
+ // Check workspace path and content.
+ if (!modelDefinesWorkspacePath(startupSetupIndex)) {
+ // Use default workspace.
+ useDefaultWorkspace(startupSetupIndex);
+ }
+
+ final String installationPath;
+ // Check installation path and content.
+ if (modelDefinesInstallationPath(startupSetupIndex)) {
+ installationPath = getInstallationPath(startupSetupIndex);
+ } else {
+ // Use default installation.
+ installationPath = useDefaultInstallation(startupSetupIndex);
+ }
+
+ progressPageLog = new ProgressPageLog(System.out);
+
+ Resource environmentSetup = rs.getResource(environmentSetupURI, true);
+ Index eclipseSetupIndex = (Index)EcoreUtil.getObjectByType(environmentSetup.getContents(),
+ SetupPackage.Literals.INDEX);
+
+ EList<ProductCatalog> productCatalogs = eclipseSetupIndex.getProductCatalogs();
+ ProductCatalog catalog = productCatalogs.get(0);
+ Product product = catalog.getProducts().get(0);
+ ProductVersion productVersion = product.getVersions().get(0);
+
+ // Add extra plugins to install from user setup model.
+ for (ProjectCatalog projectCatalog : startupSetupIndex.getProjectCatalogs()) {
+ for (SetupTask setupTask : projectCatalog.getSetupTasks()) {
+ if (setupTask instanceof P2Task) {
+ SetupTask copy = EcoreUtil.copy(setupTask);
+ catalog.getSetupTasks().add(copy);
+ }
+ }
+ for (Project project : projectCatalog.getProjects()) {
+ for (SetupTask setupTask : project.getSetupTasks()) {
+ if (setupTask instanceof P2Task) {
+ SetupTask copy = EcoreUtil.copy(setupTask);
+ catalog.getSetupTasks().add(copy);
+ }
+ }
+ }
+ }
+
+ // Create Oomph setup context.
+ final SetupContext setupContext = SetupContext.create(rs, productVersion);
+ Trigger triggerBootstrap = Trigger.BOOTSTRAP;
+ URIConverter uriConverter = rs.getURIConverter();
+ SetupTaskPerformer aPerformer;
+ try {
+ aPerformer = SetupTaskPerformer.create(uriConverter, SetupPrompter.CANCEL, triggerBootstrap,
+ setupContext, false);
+ } catch (Exception e) {
+ throw new DiesOn(DeathType.ERROR).duedTo(e).displaying("Invalid setup model").ready();
+ }
+ Confirmer confirmer = Confirmer.ACCEPT;
+ aPerformer.put(ILicense.class, confirmer);
+ aPerformer.put(Certificate.class, confirmer);
+ aPerformer.setProgress(progressPageLog);
+ aPerformer.setOffline(false);
+ aPerformer.setMirrors(true);
+
+ if (installationPathContainsExistingEclipse(installationPath)) {
+ aPerformer.getTriggeredSetupTasks().clear();
+ progressPageLog.log("Existing eclipse environment found at : " + installationPath); //$NON-NLS-1$
+ }
+
+ // Add installation task and workspace task from user setup model.
+ SetupTask installationTask = EcoreUtil.copy(getInstallationTask(startupSetupIndex));
+ aPerformer.getTriggeredSetupTasks().add(installationTask);
+ SetupTask workspaceTask = EcoreUtil.copy(getWorkspaceTask(startupSetupIndex));
+ aPerformer.getTriggeredSetupTasks().add(workspaceTask);
+
+ return aPerformer;
+ }
+
+ /**
+ * Check if the given Index defines an installation task with a non null location.
+ *
+ * @param index
+ * the given Index.
+ * @return true if the given Index defines an installation task with a non null location, false otherwise.
+ */
+ private boolean modelDefinesInstallationPath(Index index) {
+ String installationPath = getInstallationPath(index);
+ if (installationPath != null) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Search an installation task in the given Index.
+ *
+ * @param index
+ * the given Index.
+ * @return the installation task if found, null otherwise.
+ */
+ private InstallationTask getInstallationTask(Index index) {
+ for (ProjectCatalog projectCatalog : index.getProjectCatalogs()) {
+ for (SetupTask setupTask : projectCatalog.getSetupTasks()) {
+ if (setupTask instanceof InstallationTask) {
+ return ((InstallationTask)setupTask);
+ }
+ }
+ }
+ for (ProductCatalog productCatalog : index.getProductCatalogs()) {
+ for (SetupTask setupTask : productCatalog.getSetupTasks()) {
+ if (setupTask instanceof InstallationTask) {
+ return ((InstallationTask)setupTask);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Search an installation task in the given Index. If found, return his location attribute value.
+ *
+ * @param index
+ * the given Index.
+ * @return the location attribute value of the installation task if found, null otherwise.
+ */
+ private String getInstallationPath(Index index) {
+ final String path;
+ final InstallationTask task = getInstallationTask(index);
+ if (task != null) {
+ String resourcePath = index.eResource().getURI().toFileString();
+ String resourceBasePath = resourcePath.substring(0, resourcePath.lastIndexOf(SEP));
+ path = toFileWithAbsolutePath(resourceBasePath, task.getLocation()).toString();
+ } else {
+ path = null;
+ }
+ return path;
+ }
+
+ /**
+ * Check if there is an existing eclipse environment at the given path.
+ *
+ * @param installationPath
+ * the given installation path.
+ * @return true if there is an existing eclipse environment at the given path, false otherwise.
+ */
+ private boolean installationPathContainsExistingEclipse(String installationPath) {
+ if (installationPath != null) {
+ File file = new File(installationPath);
+ if (file.exists()) {
+ String[] eclipseFolder = file.list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return "eclipse".equals(name); //$NON-NLS-1$
+ }
+ });
+ if (eclipseFolder.length == 1) {
+ File eclipse = new File(installationPath + SEP + "eclipse"); //$NON-NLS-1$
+ if (eclipse.exists()) {
+ String[] eclipseExe = eclipse.list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return "eclipse".equals(name) || "eclipse.exe".equals(name); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ });
+ if (eclipseExe.length == 1) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the given Index (setup model root element) contains a workspace task with a non null
+ * workspace location.
+ *
+ * @param index
+ * the given Index (setup model root element)
+ * @return true if the given Index(setup model root element) contains a workspace task with a non null
+ * workspace location, false otherwise.
+ */
+ private boolean modelDefinesWorkspacePath(Index index) {
+ String workspacePath = getWorkspacePath(index);
+ if (workspacePath != null) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Search a workspace task in the given Index.
+ *
+ * @param index
+ * the given Index.
+ * @return the workspace task if found, null otherwise.
+ */
+ private WorkspaceTask getWorkspaceTask(Index index) {
+ for (ProjectCatalog projectCatalog : index.getProjectCatalogs()) {
+ for (SetupTask setupTask : projectCatalog.getSetupTasks()) {
+ if (setupTask instanceof WorkspaceTask) {
+ return ((WorkspaceTask)setupTask);
+ }
+ }
+ }
+ for (ProductCatalog productCatalog : index.getProductCatalogs()) {
+ for (SetupTask setupTask : productCatalog.getSetupTasks()) {
+ if (setupTask instanceof WorkspaceTask) {
+ return ((WorkspaceTask)setupTask);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Search a workspace task in the given Index. If found, return his location attribute value.
+ *
+ * @param index
+ * the given Index.
+ * @return the location attribute value of the workspace task if found, null otherwise.
+ */
+ private String getWorkspacePath(Index index) {
+ final String path;
+ final WorkspaceTask task = getWorkspaceTask(index);
+ if (task != null) {
+ String resourcePath = index.eResource().getURI().toFileString();
+ String resourceBasePath = resourcePath.substring(0, resourcePath.lastIndexOf(SEP));
+ path = toFileWithAbsolutePath(resourceBasePath, task.getLocation()).toString();
+ } else {
+ path = null;
+ }
+
+ return path;
+ }
+
+ /**
+ * If the given index hasn't defined workspace task, this method generates a unique id in the temporary
+ * folder of the system, add a new workspace task in the given Index, and set the location of this new
+ * workspace task with the generated id. If the generated id already exists (cause a command already been
+ * called with the same Index), it is reused.
+ *
+ * @param index
+ * the given Index.
+ * @return the location of the workspace.
+ * @throws Die
+ * @throws IOException
+ */
+ private String useDefaultWorkspace(Index index) throws IOException, Die {
+ String id = generateIDForSetup(index.eResource().getURI().toFileString());
+ File ws = createOrGetTempDir("emfcWs" + id); //$NON-NLS-1$
+ WorkspaceTask wsTask = SetupFactory.eINSTANCE.createWorkspaceTask();
+ wsTask.setLocation(ws.getPath());
+ EList<ProjectCatalog> projectCatalogs = index.getProjectCatalogs();
+ if (!projectCatalogs.isEmpty()) {
+ projectCatalogs.get(0).getSetupTasks().add(wsTask);
+ }
+ return ws.getAbsolutePath();
+ }
+
+ /**
+ * Creates a temporary directory in the system temp directory.
+ *
+ * @return the new created directory.
+ */
+ private static File createOrGetTempDir(String name) {
+ final File baseDir = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
+ final String baseName = name;
+
+ for (int counter = 0; counter < 10000; counter++) {
+ final File tempDir = new File(baseDir, baseName);
+ if (tempDir.exists()) {
+ return tempDir;
+ }
+ if (tempDir.mkdir()) {
+ return tempDir;
+ }
+ }
+ throw new IllegalStateException("Failed to create directory within " + 10000 + " attempts (tried "
+ + baseName + "0 to " + baseName + (10000 - 1) + ')');
+ }
+
+ /**
+ * Generate a unique ID for the a given file.
+ *
+ * @param setupFilePath
+ * the absolute path of the given file.
+ * @return a unique ID for the a given file.
+ * @throws IOException
+ * @throws Die
+ * On any other program error.
+ */
+ private static String generateIDForSetup(String setupFilePath) throws IOException, Die {
+ File f = new File(setupFilePath);
+ MessageDigest digest;
+ try {
+ digest = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ throw new DiesOn(DeathType.ERROR).duedTo(e).ready();
+ }
+ FileInputStream inputStream = new FileInputStream(f);
+ byte[] bytesBuffer = new byte[1024];
+ int bytesRead = -1;
+
+ while ((bytesRead = inputStream.read(bytesBuffer)) != -1) {
+ digest.update(bytesBuffer, 0, bytesRead);
+ }
+ inputStream.close();
+
+ byte[] hashedBytes = digest.digest();
+
+ return convertByteArrayToHexString(hashedBytes);
+ }
+
+ /**
+ * If the given index hasn't defined installation task, this method generates a unique id in the temporary
+ * folder of the system, add a new installation task in the given Index, and set the location of this new
+ * installation task with the generated id. If the generated id already exists (cause a command already
+ * been called with the same Index), it is reused.
+ *
+ * @param index
+ * the given Index.
+ * @return the location of the installation.
+ * @throws Die
+ * @throws IOException
+ */
+ private String useDefaultInstallation(Index index) throws IOException, Die {
+ String id = generateIDForSetup(index.eResource().getURI().toFileString());
+ File install = createOrGetTempDir("emfcInstall" + id); //$NON-NLS-1$
+ InstallationTask installTask = SetupFactory.eINSTANCE.createInstallationTask();
+ installTask.setLocation(install.getPath());
+ EList<ProjectCatalog> projectCatalogs = index.getProjectCatalogs();
+ if (!projectCatalogs.isEmpty()) {
+ projectCatalogs.get(0).getSetupTasks().add(installTask);
+ }
+ return install.getAbsolutePath();
+ }
+
+ /**
+ * Converts an array of bytes into a string of hexadecimal values.
+ *
+ * @param arrayBytes
+ * the given array of bytes.
+ * @return a string of hexadecimal values.
+ */
+ private static String convertByteArrayToHexString(byte[] arrayBytes) {
+ StringBuffer stringBuffer = new StringBuffer();
+ for (int i = 0; i < arrayBytes.length; i++) {
+ stringBuffer.append(Integer.toString((arrayBytes[i] & 0xff) + 0x100, 16).substring(1));
+ }
+ return stringBuffer.toString();
+ }
+
+ /**
+ * Flush the out stream. This is mainly use to handle premature exit.
+ *
+ * @throws IOException
+ * if any problem with the stream.
+ */
+ public void flushOutW() throws IOException {
+ if (out != null) {
+ out.flush();
+ }
+ }
+
+ /**
+ * Returns the user setup file associated with this command.
+ *
+ * @return the user setup file associated with this command.
+ */
+ public File getSetupFile() {
+ return setupFile;
+ }
+
+ /**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+ class StreamGobbler implements Runnable {
+ private InputStream is;
+
+ // reads everything from is until empty.
+ StreamGobbler(InputStream is) {
+ this.is = is;
+ }
+
+ public void run() {
+ try {
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ // performer.log(line);
+ out().println(line);
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/CommandFactory.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/CommandFactory.java
new file mode 100644
index 0000000..4d557b7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/CommandFactory.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Commands factory.
+ * <p>
+ * Here is where the logical command should be built.
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public final class CommandFactory {
+ /**
+ * Registry of commands.
+ */
+ private final Map<String, Class<? extends AbstractLogicalCommand>> cmds;
+
+ /**
+ * Constructor.
+ */
+ private CommandFactory() {
+ cmds = new HashMap<String, Class<? extends AbstractLogicalCommand>>(3);
+ cmds.put(LogicalMergeCommand.LOGICAL_MERGE_CMD_NAME, LogicalMergeCommand.class);
+ cmds.put(LogicalMergeToolCommand.LOGICAL_MERGE_TOOL_CMD_NAME, LogicalMergeToolCommand.class);
+ cmds.put(LogicalDiffCommand.LOGICAL_DIFF_CMD_NAME, LogicalDiffCommand.class);
+ }
+
+ /**
+ * Singleton pattern.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+ private static final class SingletonHolder {
+ /**
+ * Unique instance.
+ */
+ private static final CommandFactory INSTANCE = new CommandFactory();
+ }
+
+ public static CommandFactory getInstance() {
+ return SingletonHolder.INSTANCE;
+ }
+
+ public Collection<String> getAvailableCmd() {
+ return cmds.keySet();
+ }
+
+ /**
+ * Creates a command using its name.
+ *
+ * @param cmdName
+ * Name of the command.
+ * @return the newly created command or <code>null</code> if any error or if the command does not exist.
+ */
+ public AbstractLogicalCommand createCommand(String cmdName) {
+ AbstractLogicalCommand cmdIntance = null;
+ if (cmdName != null) {
+ Class<? extends AbstractLogicalCommand> cmdClass = cmds.get(cmdName);
+ if (cmdClass != null) {
+ try {
+ cmdIntance = cmdClass.newInstance();
+ cmdIntance.setCommandName(cmdName);
+ } catch (InstantiationException e) {
+ // If error return null
+ } catch (IllegalAccessException e) {
+ // If error return null
+ }
+ }
+ }
+ return cmdIntance;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffCommand.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffCommand.java
new file mode 100644
index 0000000..7ae979e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalDiffCommand.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.Options.SHOW_STACK_TRACE_OPT;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.args.PathFilterHandler;
+import org.eclipse.emf.compare.git.pgm.internal.args.RefOptionHandler;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.oomph.setup.util.OS;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+/**
+ * Logical diff command. <h3>Name</h3>
+ * <p>
+ * logicaldiff - Git Logical Diff
+ * </p>
+ * <h4>Synopsis</h4>
+ * <p>
+ * logicaldiff <setup> [--show-stack-trace] [--git-dir <gitDirectory>] <commit>
+ * [<compareWithCommit>] [ -- <paths...>]
+ * </p>
+ * <h4>Description</h4>
+ * <p>
+ * The logical diff is used to display differences using logical model.
+ * </p>
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("restriction")
+public class LogicalDiffCommand extends AbstractLogicalCommand {
+
+ /**
+ * Command name.
+ */
+ static final String LOGICAL_DIFF_CMD_NAME = "logicaldiff"; //$NON-NLS-1$
+
+ /**
+ * Holds the reference from which the differences should be displayed.
+ */
+ @Argument(index = 1, multiValued = false, required = true, metaVar = "<commit>", usage = "Commit ID or branch name.", handler = RefOptionHandler.class)
+ private ObjectId commit;
+
+ /**
+ * Optional reference used to view the differences between {@link #commit} and {@link #commitWith}.
+ */
+ @Argument(index = 2, multiValued = false, required = false, metaVar = "<compareWithCommit>", usage = "Commit ID or branch name. This is to view the changes between <commit> and <compareWithCommit> or HEAD if not specified.", handler = RefOptionHandler.class)
+ private ObjectId commitWith;
+
+ /**
+ * {@link TreeFilter} use to filter file on which differences should be shown.
+ */
+ @Option(name = "--", metaVar = "<path...>", multiValued = false, handler = PathFilterHandler.class, usage = "This is used to limit the diff to the named paths (you can give directory names and get diff for all files under them).")
+ private PathFilter treeFilter;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IOException
+ * @throws InterruptedException
+ * @see org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommand#internalRun()
+ */
+ @Override
+ protected Integer internalRun() throws Die {
+
+ OS os = getPerformer().getOS();
+
+ if (!os.isCurrent()) {
+ return Returns.ERROR.code();
+ }
+
+ try {
+ out().println("Launching the installed product...");
+ } catch (IOException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ String setupFileAbsolutePath = this.getSetupFile().getAbsolutePath();
+ String setupFileBasePath = Paths.get(setupFileAbsolutePath).getParent().toString();
+
+ String eclipseDir = os.getEclipseDir();
+ String eclipseExecutable = os.getEclipseExecutable();
+ File eclipseFile = EMFCompareGitPGMUtil
+ .toFileWithAbsolutePath(setupFileBasePath, Paths.get(
+ getPerformer().getInstallationLocation().getPath(), eclipseDir, eclipseExecutable)
+ .toString());
+
+ List<String> command = new ArrayList<String>();
+ command.add(eclipseFile.toString());
+ command.add("-nosplash"); //$NON-NLS-1$
+ command.add("--launcher.suppressErrors"); //$NON-NLS-1$
+ command.add("-application"); //$NON-NLS-1$
+ command.add("emf.compare.git.logicaldiff"); //$NON-NLS-1$
+
+ // Propagates the show stack trace option to the application.
+ if (isShowStackTrace()) {
+ command.add(SHOW_STACK_TRACE_OPT);
+ }
+
+ command.add(getRepository().getDirectory().getAbsolutePath());
+
+ command.add(setupFileAbsolutePath);
+
+ if (commit != null) {
+ command.add(commit.name());
+ } else {
+ command.add("HEAD"); //$NON-NLS-1$
+ }
+ if (commitWith != null) {
+ command.add(commitWith.name());
+ } else {
+ command.add("HEAD"); //$NON-NLS-1$
+ }
+ if (treeFilter != null) {
+ command.add("--"); //$NON-NLS-1$
+ command.add(treeFilter.getPath());
+ }
+
+ if (getPerformer().getWorkspaceLocation() != null) {
+ command.add("-data"); //$NON-NLS-1$
+ command.add(getPerformer().getWorkspaceLocation().toString());
+ }
+
+ command.add("-vmargs"); //$NON-NLS-1$
+ command.add("-D" + PROP_SETUP_CONFIRM_SKIP + "=true"); //$NON-NLS-1$ //$NON-NLS-2$
+ command.add("-D" + PROP_SETUP_OFFLINE_STARTUP + "=" + false); //$NON-NLS-1$ //$NON-NLS-2$
+ command.add("-D" + PROP_SETUP_MIRRORS_STARTUP + "=" + true); //$NON-NLS-1$ //$NON-NLS-2$
+ //command.add("-Xdebug"); //$NON-NLS-1$
+ //command.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8123"); //$NON-NLS-1$
+
+ ProcessBuilder builder = new ProcessBuilder(command);
+
+ Process process;
+ try {
+ process = builder.start();
+ } catch (IOException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ // output both stdout and stderr data from proc to stdout of this
+ // process
+ // StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream());
+ StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream());
+ // new Thread(errorGobbler).start();
+ new Thread(outputGobbler).start();
+
+ int returnValue;
+ try {
+ returnValue = process.waitFor();
+ } catch (InterruptedException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ return Returns.valueOf(returnValue).code();
+ }
+
+ // For testing purpose
+ ObjectId getCommit() {
+ return commit;
+ }
+
+ // For testing purpose
+ ObjectId getOptionalCommit() {
+ return commitWith;
+ }
+
+ // For testing purpose
+ TreeFilter getPathFilter() {
+ return treeFilter;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommand.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommand.java
new file mode 100644
index 0000000..da31393
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeCommand.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.Options.SHOW_STACK_TRACE_OPT;
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.args.RefOptionHandler;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.RepositoryState;
+import org.eclipse.oomph.setup.util.OS;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+/**
+ * Logical merge command. <h3>Name</h3>
+ * <p>
+ * logicalmerge - Git Logical Merge
+ * </p>
+ * <h4>Synopsis</h4>
+ * <p>
+ * logicalmerge [--show-stack-trace] [--git-dir <gitDirectory>] <setup> <commit>
+ * </p>
+ * <h4>Description</h4>
+ * <p>
+ * The logical merge command is used to merge logical models. Instead of merging each file one by one like git
+ * would do, it uses a set of semantically interconnected files. It avoids semantical breakage of models.
+ * </p>
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("restriction")
+public class LogicalMergeCommand extends AbstractLogicalCommand {
+
+ /**
+ * Command name.
+ */
+ static final String LOGICAL_MERGE_CMD_NAME = "logicalmerge"; //$NON-NLS-1$
+
+ /**
+ * Holds a ObjectId that need to be merged.
+ */
+ @Argument(index = 1, required = true, metaVar = "<commit>", usage = "Commit ID or branch name to merge.", handler = RefOptionHandler.class)
+ private ObjectId commit;
+
+ /**
+ * Optional message used for the merge commit.
+ */
+ @Option(name = "-m", metaVar = "message", required = false, usage = "Set the commit message to be used for the merge commit (in case one is created).")
+ private String message;
+
+ @Option(name = "--debug", usage = "Launched the provisonned eclipse in debug mode.", aliases = {"-d" })
+ private boolean debug;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommand#run()
+ */
+ @Override
+ protected Integer internalRun() throws Die {
+ // Checks we are not already in a conflict state
+ // Checks that the repository is in conflict state
+ if (getRepository().getRepositoryState() == RepositoryState.MERGING) {
+ StringBuilder message = new StringBuilder(
+ "error: 'merge' is not possible because you have unmerged files.").append(EOL);
+ message.append("hint: Use the logicalmergetool command to fix them up un the work tree").append(
+ EOL);
+ message.append("hint: and then use the 'git add/rm <file>' as").append(EOL);
+ message.append("hint: appropriate to mark resolution").append(EOL);
+ System.out.println(message);
+ throw new DiesOn(DeathType.FATAL).displaying("Exiting because of an unresolved conflict.")
+ .ready();
+ }
+
+ OS os = getPerformer().getOS();
+
+ if (!os.isCurrent()) {
+ return Returns.ERROR.code();
+ }
+
+ try {
+ out().println("Launching the installed product...");
+ } catch (IOException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ String setupFileAbsolutePath = this.getSetupFile().getAbsolutePath();
+ String setupFileBasePath = Paths.get(setupFileAbsolutePath).getParent().toString();
+
+ String eclipseDir = os.getEclipseDir();
+ String eclipseExecutable = os.getEclipseExecutable();
+ File eclipseFile = EMFCompareGitPGMUtil
+ .toFileWithAbsolutePath(setupFileBasePath, Paths.get(
+ getPerformer().getInstallationLocation().getPath(), eclipseDir, eclipseExecutable)
+ .toString());
+
+ List<String> command = new ArrayList<String>();
+ command.add(eclipseFile.toString());
+ command.add("-nosplash"); //$NON-NLS-1$
+ command.add("--launcher.suppressErrors"); //$NON-NLS-1$
+ command.add("-application"); //$NON-NLS-1$
+ command.add("emf.compare.git.logicalmerge"); //$NON-NLS-1$
+
+ // Propagates the show stack trace option to the application.
+ if (isShowStackTrace()) {
+ command.add(SHOW_STACK_TRACE_OPT);
+ }
+
+ command.add(getRepository().getDirectory().getAbsolutePath());
+
+ command.add(setupFileAbsolutePath);
+
+ if (commit != null) {
+ command.add(commit.name());
+ } else {
+ command.add("HEAD"); //$NON-NLS-1$
+ }
+
+ if (message != null) {
+ command.add("-m"); //$NON-NLS-1$
+ command.add(message);
+ }
+
+ if (getPerformer().getWorkspaceLocation() != null) {
+ command.add("-data"); //$NON-NLS-1$
+ command.add(getPerformer().getWorkspaceLocation().toString());
+ }
+
+ command.add("-vmargs"); //$NON-NLS-1$
+ command.add("-D" + PROP_SETUP_CONFIRM_SKIP + "=true"); //$NON-NLS-1$ //$NON-NLS-2$
+ command.add("-D" + PROP_SETUP_OFFLINE_STARTUP + "=" + false); //$NON-NLS-1$ //$NON-NLS-2$
+ command.add("-D" + PROP_SETUP_MIRRORS_STARTUP + "=" + true); //$NON-NLS-1$ //$NON-NLS-2$
+ if (debug) {
+ command.add("-Xdebug"); //$NON-NLS-1$
+ command.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8123"); //$NON-NLS-1$
+ }
+
+ ProcessBuilder builder = new ProcessBuilder(command);
+ Process process;
+ try {
+ process = builder.start();
+ } catch (IOException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ // output both stdout and stderr data from proc to stdout of this
+ // process
+ StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream());
+ StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream());
+ new Thread(errorGobbler).start();
+ new Thread(outputGobbler).start();
+
+ int returnValue;
+ try {
+ returnValue = process.waitFor();
+ } catch (InterruptedException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ return Returns.valueOf(returnValue).code();
+ }
+
+ // For testing purpose.
+ String getMessage() {
+ return message;
+ }
+
+ // For testing purpose.
+ ObjectId getCommit() {
+ return commit;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolCommand.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolCommand.java
new file mode 100644
index 0000000..fdcb640
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/cmd/LogicalMergeToolCommand.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.cmd;
+
+import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.SEP;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
+import org.eclipse.jgit.lib.RepositoryState;
+import org.eclipse.oomph.setup.util.OS;
+
+/**
+ * Logical merge tool command. <h3>Name</h3>
+ * <p>
+ * logicalmergetool - Git Logical Merge Tool
+ * </p>
+ * <h4>Synopsis</h4>
+ * <p>
+ * logicalmergetool [--show-stack-trace] <setup>
+ * </p>
+ * <h4>Description</h4>
+ * <p>
+ * The logical merge tool command is used to open a merge tool using logical model if the current repository
+ * is in conflict state.
+ * </p>
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+@SuppressWarnings("restriction")
+public class LogicalMergeToolCommand extends AbstractLogicalCommand {
+
+ /**
+ * Command name.
+ */
+ static final String LOGICAL_MERGE_TOOL_CMD_NAME = "logicalmergetool"; //$NON-NLS-1$
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.git.pgm.internal.cmd.AbstractLogicalCommand#internalRun()
+ */
+ @Override
+ protected Integer internalRun() throws Die {
+
+ // Checks that the repository is in conflict state
+ if (getRepository().getRepositoryState() != RepositoryState.MERGING) {
+ throw new DiesOn(DeathType.FATAL).displaying("No conflict to merge").ready();
+ }
+
+ OS os = getPerformer().getOS();
+
+ if (!os.isCurrent()) {
+ return Returns.ERROR.code();
+ }
+
+ try {
+ out().println("Launching the installed product...");
+ } catch (IOException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ String eclipseDir = os.getEclipseDir();
+ String eclipseExecutable = os.getEclipseExecutable();
+ String eclipsePath = new File(getPerformer().getInstallationLocation(), eclipseDir + SEP
+ + eclipseExecutable).getAbsolutePath();
+
+ List<String> command = new ArrayList<String>();
+ command.add(eclipsePath);
+
+ if (getPerformer().getWorkspaceLocation() != null) {
+ command.add("-data"); //$NON-NLS-1$
+ command.add(getPerformer().getWorkspaceLocation().toString());
+ }
+
+ command.add("-vmargs"); //$NON-NLS-1$
+ command.add("-D" + PROP_SETUP_CONFIRM_SKIP + "=true"); //$NON-NLS-1$ //$NON-NLS-2$
+ command.add("-D" + PROP_SETUP_OFFLINE_STARTUP + "=" + false); //$NON-NLS-1$ //$NON-NLS-2$
+ command.add("-D" + PROP_SETUP_MIRRORS_STARTUP + "=" + true); //$NON-NLS-1$ //$NON-NLS-2$
+
+ ProcessBuilder builder = new ProcessBuilder(command);
+ Process process;
+ try {
+ process = builder.start();
+ } catch (IOException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ // output both stdout and stderr data from proc to stdout of this
+ // process
+ StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream());
+ StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream());
+ new Thread(errorGobbler).start();
+ new Thread(outputGobbler).start();
+
+ int returnValue;
+ try {
+ returnValue = process.waitFor();
+ } catch (InterruptedException e) {
+ throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
+ }
+
+ return Returns.valueOf(returnValue).code();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/exception/ArgumentValidationError.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/exception/ArgumentValidationError.java
new file mode 100644
index 0000000..82f4e51
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/exception/ArgumentValidationError.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.exception;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+
+/**
+ * This exception is raised when a argument on the command line failed the validation process.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class ArgumentValidationError extends CmdLineException {
+
+ /**
+ * Serial id.
+ */
+ private static final long serialVersionUID = -8121393950063566490L;
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * {@link CmdLineException#CmdLineException(CmdLineParser, String)}
+ * @param message
+ * {@link CmdLineException#CmdLineException(CmdLineParser, String)}
+ */
+ public ArgumentValidationError(CmdLineParser parser, String message) {
+ super(parser, message);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parser
+ * {@link CmdLineException#CmdLineException(CmdLineParser, Throwable)}
+ * @param cause
+ * {@link CmdLineException#CmdLineException(CmdLineParser, Throwable)}
+ */
+ public ArgumentValidationError(CmdLineParser parser, Throwable cause) {
+ super(parser, cause);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/exception/Die.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/exception/Die.java
new file mode 100644
index 0000000..5200511
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/exception/Die.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.exception;
+
+/**
+ * Exception to be raised on error in this application.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public final class Die extends Exception {
+ /**
+ * .
+ */
+ private static final long serialVersionUID = 1907077670315070835L;
+
+ /**
+ * Type of death of the application.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+ public enum DeathType {
+ /**
+ * Major error the software stopped somewhere it should not.
+ */
+ SOFTWARE_ERROR,
+ /**
+ * Program terminated on a error.
+ */
+ ERROR,
+ /**
+ * Program terminated on a error which is prefixed with fatal.
+ */
+ FATAL,
+ }
+
+ /**
+ * Type of death.
+ *
+ * @see DeathType
+ */
+ private final DeathType type;
+
+ /**
+ * Private constructor.
+ *
+ * @param type
+ * Type of death
+ * @param message
+ * Message displayed to the user.
+ * @param cause
+ * Cause of the death.
+ * @see DiesOn
+ */
+ private Die(DeathType type, String message, Throwable cause) {
+ super(message, cause);
+ this.type = type;
+ }
+
+ /**
+ * Private constructor.
+ *
+ * @param type
+ * Type of death
+ * @param cause
+ * Cause of the death.
+ * @see DiesOn
+ */
+ private Die(DeathType type, Throwable cause) {
+ super(cause);
+ this.type = type;
+ }
+
+ /**
+ * Get the type of death.
+ *
+ * @return {@link DeathType}
+ */
+ public DeathType getType() {
+ return type;
+ }
+
+ /**
+ * Facilities used to create understandable exceptions.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+ public static class DiesOn {
+
+ /**
+ * Type of the death.
+ */
+ private final DeathType type;
+
+ /**
+ * Message to display to the user.
+ */
+ private String message;
+
+ /**
+ * Cause of the death.
+ */
+ private Throwable cause;
+
+ /**
+ * Constructor.
+ *
+ * @param deathType
+ * type of the death.
+ */
+ public DiesOn(DeathType deathType) {
+ this.type = deathType;
+ }
+
+ /**
+ * Sets the cause of the death.
+ *
+ * @param aCause
+ * .
+ * @return this.
+ */
+ public DiesOn duedTo(Throwable aCause) {
+ this.cause = aCause;
+ return this;
+ }
+
+ /**
+ * Sets the message to be displayed to the user.
+ *
+ * @param aMessage
+ * message to display.
+ * @return this.
+ */
+ public DiesOn displaying(String aMessage) {
+ this.message = aMessage;
+ return this;
+ }
+
+ /**
+ * Declares this exception ready to be thrown.
+ *
+ * @return a newly created {@link Die}.
+ */
+ public Die ready() {
+ if (message == null) {
+ return new Die(type, cause);
+ } else {
+ return new Die(type, message, cause);
+ }
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/util/EMFCompareGitPGMUtil.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/util/EMFCompareGitPGMUtil.java
new file mode 100644
index 0000000..8bdac9b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/util/EMFCompareGitPGMUtil.java
@@ -0,0 +1,134 @@
+package org.eclipse.emf.compare.git.pgm.internal.util;
+
+import com.google.common.base.Strings;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.compare.git.pgm.Returns;
+import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
+
+public class EMFCompareGitPGMUtil {
+
+ /**
+ * File separator.
+ */
+ public static final String SEP = File.separator;
+
+ /**
+ * End of line.
+ */
+ public static final String EOL = System.getProperty("line.separator"); //$NON-NLS-1$
+
+ /**
+ * Empty string.
+ */
+ public static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ /**
+ * Current Folder.
+ */
+ public static final String CURRENT = "."; //$NON-NLS-1$
+
+ /**
+ * Parent Folder.
+ */
+ public static final String PARENT = ".."; //$NON-NLS-1$
+
+ /**
+ * Displays the error message to the user and return matching {@link Returns}.
+ *
+ * @param error
+ * Error to handle.
+ * @param showStackTrace
+ * Set to <code>true</code> if the stack trace should be display in the console or
+ * <code>false</code> otherwise.
+ * @return a {@link Returns}
+ */
+ public static Integer handleDieError(Die error, boolean showStackTrace) {
+ final PrintStream stream;
+ final Integer returnCode = Returns.ERROR.code();
+ final String prefix;
+ switch (error.getType()) {
+ case ERROR:
+ prefix = "error: ";
+ stream = System.out;
+ break;
+ case FATAL:
+ prefix = "fatal: ";
+ stream = System.out;
+ break;
+ case SOFTWARE_ERROR:
+ default:
+ prefix = "software error: ";
+ stream = System.err;
+ break;
+ }
+ if (error.getMessage() != null) {
+ stream.println(prefix + error.getMessage());
+ }
+ if (showStackTrace && error.getCause() != null) {
+ error.getCause().printStackTrace(stream);
+ }
+
+ return returnCode;
+ }
+
+ /**
+ * Upstream, based on branch 'master' of git@github.com:adaussy/EMFCompareGitPGM.git Returns, from a
+ * relative path, the corresponding file with an absolute path. This absolute path is computed against
+ * 'user.dir' system property.
+ *
+ * @param relativePath
+ * the relative path for which we want the corresponding file.
+ * @return the corresponding file with an absolute path.
+ */
+ public static File toFileWithAbsolutePath(String relativePath) {
+ return toFileWithAbsolutePath(System.getProperty("user.dir"), relativePath); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns, from a relative path, the corresponding file with an absolute path. This absolute path is
+ * computed against the given base path.
+ *
+ * @param relativePath
+ * the relative path for which we want the corresponding file.
+ * @return the corresponding file with an absolute path.
+ */
+ public static File toFileWithAbsolutePath(String basePath, String relativePath) {
+ File file = new File(relativePath);
+ if (!file.isAbsolute()) {
+ Path base = FileSystems.getDefault().getPath(basePath);
+ Path resolvedPath = base.resolve(file.toPath());
+ Path absolutePath = resolvedPath.normalize();
+ file = absolutePath.toFile();
+ }
+ return file;
+ }
+
+ /**
+ * Get a nice message from a IStatus.
+ *
+ * @param status
+ * @return
+ */
+ public static String getStatusMessage(IStatus status) {
+ StringBuilder statusMessage = new StringBuilder(status.getMessage());
+ if (status.isMultiStatus()) {
+ appendChildrenStatus(status, statusMessage, 1);
+ }
+ return statusMessage.toString();
+ }
+
+ private static void appendChildrenStatus(IStatus status, StringBuilder builder, int depth) {
+ for (IStatus child : status.getChildren()) {
+ builder.append(Strings.repeat(" ", depth)).append(child.getMessage()).append(EOL); //$NON-NLS-1$
+ if (child.isMultiStatus()) {
+ appendChildrenStatus(child, builder, depth + 1);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/util/FunctionCatalog.java b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/util/FunctionCatalog.java
new file mode 100644
index 0000000..d855560
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.git.pgm/src/org/eclipse/emf/compare/git/pgm/internal/util/FunctionCatalog.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.git.pgm.internal.util;
+
+import com.google.common.base.Function;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.oomph.resources.SourceLocator;
+
+/**
+ * A catalog of helpfull {@link Function}.
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class FunctionCatalog {
+
+ private FunctionCatalog() {
+ }
+
+ public static final Function<File, String> FILE_TO_PATH = new Function<File, String>() {
+
+ public String apply(File input) {
+ return input.getAbsolutePath();
+ }
+ };
+
+ public static final Function<IProject, File> IPROJECT_TO_FILE = new Function<IProject, File>() {
+ public File apply(IProject input) {
+ return new File(input.getLocation().toString());
+ }
+ };
+
+ public static final Function<SourceLocator, File> SOURCELOCATOR_TO_FILE = new Function<SourceLocator, File>() {
+ public File apply(SourceLocator input) {
+ return new File(input.getRootFolder());
+ }
+ };
+
+}