gpyfm-tutorial
From Genunix
Download the example tar ball. This contains the following:
gpyfm file merge utility
fm/ file merge python package
contrived/ the "gate" for our tutorial
ws-0/ a workspace for our tutorial
ws-1/ a workspace for our tutorial
You can't have conflicts without at least two workspaces.
The gate and workspaces have been set up with mercurial. The workspaces use relative paths to the "gate". You do not need to "hg init" or "hg clone", that has already been taken care of.
Additionally the changes in the workspaces have been committed, and are ready for you to push back (and possibly merge).
Take a look at contrived/contrivedex.c. This is a contrived example source file that we will be using to see how gpyfm handles simple merges. The program uses pthreads to make deposits that change the global variable balance. balance is not protected by a mutex so there is a large bug in this file. We'll return to this bug shortly.
Although for the tutorial you don't need to try it, you can build and run "contrivedex". The python script loop repeadedly runs "contrivedex" until the race causes the program to compute an incorrect final balance.
In order for a merge to be necessary an "hg push" will have to happen from one of the workspaces. Start with ws-0:
cd ws-0/contrived
If you want to see what changes are about to go back do the following:
hg diff -r0 -r1
Notice ws-0 is fixing the race around balance.
hg push ../../contrived
pushing to ../../contrived
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
Now go over to ws-1 and pull changes _after_ setting up HGMERGE environment variable:
cd ../../ws-1/contrived
This workspace is adding a withdrawal() function to complement deposit():
hg diff -r0 -r1
Notice withdrawal() has the same bug the original deposit() had. In order to get to a merge do the following:
HGMERGE=../../gpyfm
export HGMERGE
hg pull ../../contrived
pulling from ../../contrived
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
Notice mercurial wants you to merge changes. So do just that:
hg merge
You may see errors if you didn't run hg merge locally and didn't set the DISPLAY or if you don't have pygtk installed. If that is the case do as mercurial instructs:
hg update -C 1
Try again once your X11/pygtk issues are solved:
hg merge
You should be presented with gpyfm GUI. All your controls are along the top
I've labeled the main areas:
A. The main button bar.
B. Navigation and Diff buttons specific to parent or child
C. General navigation.
Not all buttons are available at all times. For example you can't save until you have resolved all conflicts. You can't quit until you have saved.
Clicking "Next" takes you to the next unresolved diff for the parent or child (depending upon which one you click). The arrows cycle you through diffs in order, resolved or unresolved.
When you start gpyfm, the text views are scrolled so that the 1st diff is in the middle of either the parent or child. gpyfm does not insert white space into any of the text windows. Try scrolling to see how the line mapping works. gpyfm will always try to have similar lines of text in the _middle_ of each window.
Also notice the color of the change and the symbols next to the line. These symbols,
'+', '-', and '|' are called indications and have the traditional diff utility meanings.
An indication with a box around it means it is the current diff being considered.
You may either "Accept" it or "Reject" it. Indications are also placed in the merge
window to show where text will be inserted or which lines are to be either deleted or
replaced. When you "Accept" or "Reject" a diff, the indication changes color as well.
Here is what happens if we accept the 1st diff:
Instead of accepting diffs one at a time, you may be able to auto-merge using the "Merge" button on the main button bar.
After that, notice that "save" and "undo" are now available. Undo is not just for diffs. The button becomes available after you type in the merge window as well. If you are familiar with TeamWare filemerge, gpyfm differs here. All actions can be undone, not just diffs.
Even in this contrived example you will have a bad merge if you just auto-merge, save, and quit. gpyfm only knows about diffs. As far as the tool is concerned you may save any time there are no more conflicts to resolve (meaning you have "Accepted" or "Rejected" everything). That _never_ means you are done.
One point of this tutorial is to show the limitation of any file merging utility.
As you cycled through the diffs with the arrows you need to notice this in the parent:
This shows a paradigm change in the code base. Locking is just one example. If you don't notice the paradigm change, you will re-introduce the same bug in your new function! Had ws-1 pushed 1st, the same would apply when merging ws-0.
There is no way to fix this but to manually type (or copy/paste) these lines into the
merge window after accepting the diff:
Webrev is only a two way diff, so the paradigm shift will not be hilighted for your code reviewers. You should not be relying upon others to spot changes with less information than gpyfm is giving you at the point of the merge.
OK, now its safe to "save". Notice "quit" becomes available. By quitting the merged file over-writes your old copy. If you destroy the window, the merge is aborted and mercurial will give you this warning:
merging contrivedex.c
merging contrivedex.c failed!
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
There are unresolved merges, you can redo the full merge using:
hg update -C 1
hg merge 2
Follow mercurial's instructions to try merging again.
After you have successfully merged the file you will see this:
merging contrivedex.c
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
You can now "hg commit" and "hg push" your merged file. XXX merge queue?
Summary: gpyfm is just a tool to help you merge your changes. In order to merge correctly you really do need to look at all the diffs. CONSTANT VIGILANCE!
