When a user wants to compare or merge EMF models from the git command line interface, the operation is doing in a textual way. If he wants to compare or merge EMF models the needs in a logical way, he needs to do that in an Eclipse environment similar to the one he used to create these models. As such, the environment requires some plugins to be installed but it may also requires some preferences to be set, some perspective to be activated etc.. Among these plugins, there are the mandatory ones that will be use to do the compare/merge operation: EMF Compare and EGit.
EMF Compare provides additional git commands in order to compare and merge models on the command line. These commands will use an Eclipse as an headless application (no Graphical User Interface) including EMF Compare and Egit to compare models in a logical way. To provisioned such Eclipse environment, the new git commands will call a program using Oomph.
Oomph Oomph is a technology that provisions a set of plugins in an Eclipse IDE, clones Git repositories, binds Git repositories to this IDE, checks projects, sets workspace preferences... The configuration is model driven, with files called Oomph setup model files.
The basics git commands don't allow to compare or merge EMF models in a logical way. Additional git commands must be added to your system. Each git command is a shell script describing its behaviour. So, to add a new git command, a new script has to be developed. The new scripts corresponding to the git commands are:
These scripts must be added on each computer that need to do "models compatible" git operations from command line interface, to enable them.
You can find the scripts at the following address: EMF Compare Git Scripts.
Note that the location of these scripts must be on your PATH environment variable. Also, they must have execution permission.
These scripts will execute a program named emfcompare-git-pgm. You also have to retrieve this program on your system. Once retrieved, you will have to export a variable named EMF_COMPARE_GIT_PGM_PATH with the path of folder containing the program emfcompare-git-pgm as value.
You can find the program at the following address: EMF Compare Git PGM. Download the one corresponding to your system.
The setup file will allow you to configure the headless application used by your command. To create a setup file you need an Eclipse environment with the Setup Model for EMF Compare's Git commands Wizard plugin installed. Add the following p2 repository (update-site) in your update manager (in Eclipse, Help Menu > Install New Software..., Add... button on the top right corner): EMF Compare's Git commands Wizard plugin update-site
Then, select the EMF Compare Git PGM Wizards > EMF Compare Git PGM Oomph Wizard Feature and click on Finish.
This tool requires Oomph 1.0.0 or later. You may need to add the Oomph update site to the list of the available update sites to be able install and/or update Oomph: http://download.eclipse.org/oomph/updates
To create a new setup model for EMF Compare's git commands, select File > New > Other ... > Oomph > Setup Model for EMF Compare's Git commands. Then click Next >.
The first page of the wizard asks you to select the project that will contain the setup model, and name that setup model. Then click Next >.
The last page of the wizard asks you to set:
Once all parameters have been set, click Finish.
Once created, you will able to modify the setup model. You can also create a setup model file from scratch if you prefer. This setup model can contains:
Please visit Oomph website for more details about Oomph.
You can find an example of setup model file for EMF compare's Git commands here: Setup Example This example contains a workspace location to edit, an installation location to edit, and additional plugins to take into account for the git command to execute. These additional plugins are Papyrus, UML2, GMF, and EMF Compare extensions.
The logicaldiff command is the "models compatible" version of the git diff command. To see a full description of the git diff command, please visit http://git-scm.com/docs/git-diff.
The command is specified as below:
git logicaldiff [--git-dir <path>] <setup> <commit> [ <commit>] [-- <path>]
To see the changes between a revision and the HEAD revision, you should omit the second commit.
git logicaldiff [--git-dir <path>] <setup> <commit> [--] [ <path>...]
In all cases, <commit> can refers to a branch name or a commit id. In all cases, [-- <path>] option allows to filter the diff command only on files that match the <path>. In all cases, [--git-dir <path>] option allows to specify a git repository (if the command is not run inside a repository)
[--show-stack-trace]
Use this option to display java stack trace in console on error.
[--help (or -h)]
Dispays help for this command.
The logicalmerge command is the "models compatible" version of the git merge command. To see a full description of the git merge command, please visit http://git-scm.com/docs/git-merge.
The command is specified as below:
git logicalmerge [--git-dir <path>] <setup> <commit>
Assume the following history exists and the current branch is master:
A---B---C topic / D---E---F---G master
Then git logicalmerge mySetupModel.setup topic will replay the changes made on the topic branch since it diverged from master (i.e., E) until its current commit © on top of master, and record the result in a new commit along with the names of the two parent commits and a log message from the user describing the changes.
A---B---C topic / \ D---E---F---G---H master
You can also replace the topic branch name by his commit id:
git logicalmerge mySetupModel.setup 87ad5ff
In all cases, <commit> can refers to a branch name or a commit id. In all cases, [--git-dir <path>] option allows to specify a git repository (if the command is not run inside a repository)
[-m message]
Set the commit message to be used for the merge commit (in case one is created).
[--show-stack-trace]
Use this option to display java stack trace in console on error.
[--help (or -h)]
Dispays help for this command.
The logicalmergetool command is the "models compatible" version of the git mergetool command. To see a full description of the git mergetool command, please visit http://git-scm.com/docs/git-mergetool.
Here is the constructions allowed for the git logicalmergetool:
git logicalmergetool <setup>
Run logical merge conflict resolution tools to resolve logical merge conflicts. In our case, it will launch an Eclipse platform with all the tools needed to resolve the conflict(s) induced by the merge. To do so, in the Eclipse environment, select the conflicting file(s) and open the contextual menu Team > Merge Tool. Once the conflict has been resolved, add the file to the index (staged area). And then commit.
The logicalcherry-pick command is the logical version of the git cherry pick command. To see a full description of the git cherry-pick command, please visit http://git-scm.com/docs/git-cherry-pick.
The command is specified as below:
git logicalcherry-pick <setup> <commit>...
Assume the following history exists and the current branch is
master:
A---B---C topic
/
D---E---F---G master,HEAD
Then git logicalcherry-pick mySetupModel.setup A B C
will pick A,B and C commits on top of the current HEAD (in the order defined by the command).
A---B---C topic
/
D---E---F---G---A---B---C master,HEAD
In all cases, <commit> can refers to a branch name or a commit id.
If cherry-picking a commit introduces a conflict, you will have to choose how to handle it. The first option is to resolve it by using:
git logicalmergetool <setup>
It opens an Eclipse platform in which you will be able to merge the differences using the merge tool (see Git mergetool command with models : git logicalmergetool). Once you have resolved all the conflicts, add the related file to the index and close your platform. To do so you can:
By the way, you can notice in the top right corner there is an Abort, Skip Commit and Continue button. This simply means that there is a interactive rebase in progress. Indeed, in EGit, cherry-picking commits is equivalent to doing an interactive rebase with only pick actions. From now on, you can either choose to continue with in UI mode (that is to say using those buttons) or go back to command line tool by closing the Eclipse platform. This documentation only describes the mechanism of the command line tool.
Once you have resolved all the conflicts, please hit:
git logicalcherry-pick <setup> --continue
This command will continue an in going cherry-pick. Be careful you have to resolve all conflicts before using this command otherwise you might get the following message:
fatal: Some files are in conflict:
project/file.ecore
project/file2.ecore
hint: You must edit all merge conflicts and then
hint: mark them as resolved using git add.
There is a major diffference with the merge workflow. While cherry-picking you should not commit by yourself the files but only add them to the index. If you do, you might receive the following message when you use the
--continue option.
No changes detected If there is nothing left to stage, chances are that something else already introduced the same changes; you might want to skip this patch using git logicalcherry-pick --quit
You can simply use the --quit option to continue your cherry-pick operation (see Quit option).
A second solution while encountering a conflict is to abort the whole cherry-pick operation. To do so please hit:
git logicalcherry-pick <setup> --abort
It reverts all the commits already cherry-picked to retrieve the state before the cherry-pick command.
The last solution you have while facing a conflict would be to "skip" the current commit and go on with the remaining commits. To do so please hit:
git logicalcherry-pick <setup> ''--quit'
The --quit option is quite different than the --quit option of the cherry-pick command in CGit. Instead of quitting an in going cherry-pick, it skips the current commit. Indeed, as mentionned above, in EGit a cherry-pick is replaced by a interactive rebase. This is why the --quit option is more like the --skip option of an interactive rebase.
[--git-dir <path>]
To specify the .git folder of a repository. This can be use to execute a command outside a git repository.
[--show-stack-trace]
Use this option to display java stack trace in console on error.
[--help (or -h)]
Dispay help for this command.
[--debug (or -d)]
Give the opportinity to connect a remote debugger to the logical cherry-pick application (using port 8123).
The logicalrebase command is the logical version of the git rebase command. To see a full description of the git rebase command, please visit http://git-scm.com/docs/git-rebase.
The command is specified as below:
git logicalrebase [<upstream>] [<branch>]
[<upstream>]
Optional parameter used to reference the target commit on top of which the branch [<branch>] will be rebased. It can either be the name of a branch, the id of a commit or the name of tag. If only one parameter is given, the software will consider it to be the upstream parameter and set [<branch>] to HEAD.
Assume the following history exists and the current branch is
topic:
A---B---C topic, HEAD
/
D---E---F---G master
Then git rebase mySetupModel.setup master
will rebase the branch
topic on top of
master.
D---E---F---G---A---B---C master, topic, HEAD
[<branch>]
Optional parameter used to reference what is going to be rebased. It can either be the name of a branch, the id of a commit or the name of tag.
For example, assume the following history exists and the current branch is
master:
A---B---C topic
/
D---E---F---G master, HEAD
Then git rebase mySetupModel.setup master topic
will checkout the branch
topic and the rebase it on top of
master.
D---E---F---G---A---B---C master, topic, HEAD
Hint to remember the parameter order:
git rebase mySetupModel.setup master
= Rebase on
master the HEAD
git rebase mySetupModel.setup master topic
= Rebase on
master the branch
topic
git rebase mySetupModel.setup master topic
equivalent to git rebase mySetupModel.setup master
if HEAD is on same commit than topic.If you do not specify any branch, git rebase mySetupModel.setup
will try to rebase the current branch on top of its remote tracking branch (see branch.<name>.remote and branch.<name>.merge options in
git-config).
For example, assume the following history exists. The current branch is
master which tracks the remote branch
origin/master:
A---B---C origin/master / D---E---F---G master, HEAD
Then git rebase mySetupModel.setup
will rebase
master on top of
origin/master.
D---E---A---B---C---F---G master, origin/master, HEAD
If rebasing a commit introduces a conflict, you will have to choose how to handle it. The first option is to resolve it by using:
git logicalmergetool <setup>
It opens an Eclipse platform in which you will be able to merge the differences using the merge tool (see Git mergetool command with models : git logicalmergetool). Once you have resolved all the conflicts, add the related file to the index and close your platform. To do so you can:
By the way, you can notice in the top right corner there is an Abort, Skip Commit and Continue button. This simply means that there is a interactive rebase in progress. Indeed, in EGit, even a normal rebase operation is equivalent to doing an interactive rebase with only pick actions. From now on, you can either choose to continue with in UI mode (that is to say using those buttons) or go back to command line tool by closing the Eclipse platform. This documentation only describes the mechanism of the command line tool.
Once you have resolved all the conflicts, please hit:
git logicalrebase <setup> --continue
This command will continue an in going rebase. Be careful you have to resolve all conflicts before using this command otherwise you might get the following message:
fatal: Some files are in conflict:
project/file.ecore
project/file2.ecore
hint: You must edit all merge conflicts and then
hint: mark them as resolved using git add.
There is a major diffference with the merge workflow. While rebasing you should not commit by yourself the files but only add them to the index. If you do, you might receive the following message when you use the
--continue option.
No changes - did you forget to use 'git add'? If there is nothing left to stage, chances are that something else already introduced the same changes; you might want to skip this patch. When you have resolved this problem, run "git logicalrebase --continue". If you prefer to skip this patch, run "git logicalrebase --skip" instead. To check out the original branch and stop rebasing, run "git logicalrebase --abort".
You can simply use the --skip option to continue your rebase operation (see Skip option).
A second solution while encountering a conflict is to abort the whole rebase operation. To do so please hit:
git rebase <setup> --abort
The last solution you have while facing a conflict, would be to "skip" the current commit and go on with the remaining commits to rebase. To do so please hit:
git rebase <setup> --quit
[--git-dir <path>]
To specify the .git folder of a repository. This can be use to execute a command outside a git repository.
[--show-stack-trace]
Use this option to display java stack trace in console on error.
[--help (or -h)]
Dispay help for this command.
The logicalpull command is the logical version of the git pull command. To see a full description of the git pull command, please visit http://git-scm.com/docs/git-pull.
The command is specified as below:
git logicalpull <setup>
Assume the following history exists and the current branch is master:
A---B---C master on origin / D---E---F---G master ^ origin/master in your repository
Basically a git logicalpull is a git fetch followed by a git logicalmerge of the fetched branch. So git logicalpull mySetupModel.setup will fetch and replay the changes from the remote master branch since it diverged from the local master (i.e., E) until its current commit ( C) on top of master, and record the result in a new commit along with the names of the two parent commits and a log message from the user describing the changes.
A---B---C origin/master / \ D---E---F---G---H master
If the command introduces conflicts, you will have to launch the git logicalmergetool to resolve them.
[--show-stack-trace]
Use this option to display java stack trace in console on error.
[--help (or -h)]
Dispays help for this command.
The first time the product is launched a stack trace is displayed in the console(see below). This error does not prevent the product to be used however it may be misleading for users. After the first launch this error disappears.
org.osgi.framework.BundleException: Could not resolve module: org.eclipse.equinox.ds [2] Unresolved requirement: Import-Package: org.eclipse.equinox.internal.util.event; version="1.0.0" at org.eclipse.osgi.container.Module.start(Module.java:434) at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582) at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562) at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533) at org.eclipse.osgi.container.SystemModule.startWorker(SystemModule.java:242) at org.eclipse.osgi.container.Module.doStart(Module.java:571) at org.eclipse.osgi.container.Module.start(Module.java:439) at org.eclipse.osgi.container.SystemModule.start(SystemModule.java:172) at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:393) at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:412) at org.eclipse.osgi.launch.Equinox.start(Equinox.java:115) at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarter.java:318) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:231) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603) at org.eclipse.equinox.launcher.Main.run(Main.java:1465) at org.eclipse.equinox.launcher.Main.main(Main.java:1438)
A bug has been reported concerning this error: https://bugs.eclipse.org/bugs/show_bug.cgi?id=453432
If you try to cherry-pick a commit that introduces changes that already belong to the worktree, the operation may stop on a dirty state. For example, if you have cherry-picked a commit that belongs to the ancestor tree of HEAD. The characteristics of this dirty state are:
This problem comes from a EGit/JGit problem (see bug 451159). A workaround would be to find the previous position of HEAD using the git reflog command. Then, use the git reset --hard {$CommitId}. This will reset HEAD to its previous position ( Use with caution).