Specifics of FCM

This aims to explain and provide tutorial examples for the following topics:

    Repository setup Specifics

Now lets do the Specificss Quiz if you have not already done it at the end of the Essentials section to see how much you already know and what we will need to focus on in this section.

Specifics Quiz

Repository setup

Please run the following tutorial repositories script if you have not already done so by running the script it will set-up the repositories that you will need for all of the tutorials. WARNING: This script adds and creates if required keywords the file ~/.metomi/fcm/keywords.cfg if the file already exists it copies the orginal to ~/.metomi/fcm/keywords_orig1.cfg. If you rerun the script it will do the same but re-number older versions of the configuation file keeping all version. Please monitor the number of these that you have and tidy up the folder periodically keeping only the desired versions.

If at any stage the repository gets corrupted then we can start again:

cd
# Warning this tearsdown the whole repository to start from scratch.
rm -rf ~/fcm_tutorial
rm -rf ~/my_fcm_tutorial
# The tutorial repositories script
tutorial_repo_setup

All of the tutorial sections are separate and do not depend on each other therefore it is safe to teardown the repositories. The only issue may be that the revision numbers do not match, but that is not important for the tutorials.

Specifics Tutorials I

fcm merge --custom (--revision)

If --custom is specified as an option to fcm merge, then the command can be used in one of two forms:

  1. fcm merge --custom --revision N:M SOURCE This is a custom merge, it performs a custom merge from the specified changeset(s) of SOURCE into the working copy. The SOURCE must be a valid URL[@REV] of a branch. If a single revision is specified, the merge delta is (N - 1):N of the SOURCE. Otherwise, the merge delta is N:M of SOURCE, where M < N.
  2. How can we find out what version of the trunk the branch branch_merge_custom was created from?

    How can we compare and find out what changes have been made to the the branch branch_merge_custom2 which was created from the now HEAD of the trunk, which has been updated since the branch was created from the trunk?

      
      cd ~/my_fcm_tutorial/specifics/branch_merge_custom
      fcm info
      
      Path: .
      Working Copy Root Path: /net/$HOME/my_fcm_tutorial/specifics/branch_merge_custom
      URL: file:///$HOME/fcm_tutorial/repository/specifics/branches/dev/$LOGNAME/r36_branch_merge_custom
      Relative URL: ^/specifics/branches/dev/$LOGNAME/r36_branch_merge_custom
      Repository Root: file:///$HOME/fcm_tutorial/repository
      Repository UUID: 0ab956ee-d466-4a5f-b005-2573ac924882
      Revision: 37
      Node Kind: directory
      Schedule: normal
      Last Changed Author: $LOGNAME
      Last Changed Rev: 37
      Last Changed Date: 2016-02-02 16:33:58 +0000 (Tue, 02 Feb 2016)
      
      fcm log -v
      
      ------------------------------------------------------------------------
      r37 | $LOGNAME | 2016-02-02 16:42:29 +0000 (Tue, 02 Feb 2016) | 1 line
      Changed paths:
         A /specifics/branches/dev
         A /specifics/branches/dev/$LOGNAME
         A /specifics/branches/dev/$LOGNAME/r36_branch_merge_custom (from /specifics/trunk:36)
      
      Made a branch Created file:///$HOME/fcm_tutorial/repository/specifics/branches/dev/$LOGNAME/r36_branch_merge_custom from /trunk@31.
      ------------------------------------------------------------------------
      r36 | $LOGNAME | 2016-02-02 16:42:29 +0000 (Tue, 02 Feb 2016) | 1 line
      Changed paths:
         A /specifics/etc/readme.txt
         A /specifics/tree_conflict.txt
      
      These changes to the trunk are for setting up a trunk repository so that it has all the files and directories that are needed for the Specifics tutorial section.
      ------------------------------------------------------------------------
      r35 | $LOGNAME | 2016-02-02 16:42:28 +0000 (Tue, 02 Feb 2016) | 1 line
      Changed paths:
         A /specifics/etc
      
      Adding the pin/ directory.
      ------------------------------------------------------------------------
      r34 | $LOGNAME | 2016-02-02 16:42:27 +0000 (Tue, 02 Feb 2016) | 1 line
      Changed paths:
         A /specifics/lib/readme_only.py
      
      Change made to correct the properties on readme_only.py using propdel svn:executable
      ------------------------------------------------------------------------
      r33 | $LOGNAME | 2016-02-02 16:42:27 +0000 (Tue, 02 Feb 2016) | 1 line
      Changed paths:
         A /specifics/ever_growing_file.dat
      
      Change made to provide a .dat file that we would want to ignore using propset svn:ignore
      ------------------------------------------------------------------------
      r32 | $LOGNAME | 2016-02-02 16:42:27 +0000 (Tue, 02 Feb 2016) | 1 line
      Changed paths:
         A /specifics/lib
         A /specifics/lib/my_hello_script.py
      
      Change made to correct the properties on my_hello_script.py using propset svn:executable ON
      ------------------------------------------------------------------------
      r30 | $LOGNAME | 2016-02-02 16:42:25 +0000 (Tue, 02 Feb 2016) | 1 line
      Changed paths:
         A /specifics
      
      New folder specifics
      ------------------------------------------------------------------------
      
      cd ~/my_fcm_tutorial/specifics
      fcm sw fcm fcm:fcm_sp/branches/dev/${LOGNAME}/r36_branch_merge_custom2
      fcm info
      
      Path: .
      Working Copy Root Path: /net/$HOME/my_fcm_tutorial/specifics/r36_branch_merge_custom2
      URL: file:///$HOME/fcm_tutorial/repository/specifics/r36_branch_merge_custom2
      Relative URL: ^/specifics/r_36branch_merge_custom2
      Repository Root: file:///$HOME/fcm_tutorial/repository
      Repository UUID: 0ab956ee-d466-4a5f-b005-2573ac924882
      Revision: 55
      Node Kind: directory
      Schedule: normal
      Last Changed Author: $LOGNAME
      Last Changed Rev: 55
      Last Changed Date: 2016-02-02 16:42:34 +0000 (Tue, 02 Feb 2016)
      
      fcm log -v
      
      ------------------------------------------------------------------------
      r55 | $LOGNAME | 2016-02-06 16:45:45 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/branches/dev/$LOGNAME/r36_branch_merge_custom2 (from /specifics/trunk:54)
      
      Made a branch Created file:///$HOME/fcm_tutorial/repository/specifics/branches/dev/$LOGNAME/r36_branch_merge_custom2 from /trunk@31.
      ------------------------------------------------------------------------
      r54 | $LOGNAME | 2016-02-06 16:45:45 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         M /specifics/etc/amazing_rock.txt
      
      Adding more to the list of amazing rock bands.
      ------------------------------------------------------------------------
      r53 | $LOGNAME | 2016-02-06 16:45:44 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         M /specifics/etc/90s_pop.txt
      
      Adding a honest comment to the file etc/90s_pop.txt.
      ------------------------------------------------------------------------
      r52 | $LOGNAME | 2016-02-06 16:45:44 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/etc/90s_pop.txt
      
      Adding a list of my fav 90's pop bands.
      ------------------------------------------------------------------------
      r51 | $LOGNAME | 2016-02-06 16:45:44 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         M /specifics/etc/amazing_rock.txt
      
      This list is endless but it needed some amazing oldies.
      ------------------------------------------------------------------------
      r50 | $LOGNAME | 2016-02-06 16:45:44 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/etc/amazing_rock.txt
      
      Adding a list of the rock bands that I enjoy.
      ------------------------------------------------------------------------
      r49 | $LOGNAME | 2016-02-06 16:45:44 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/etc
      
      Adding the etc/ directory.
      ------------------------------------------------------------------------
      r36 | $LOGNAME | 2016-02-06 16:45:41 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/etc/readme.txt
         A /specifics/tree_conflict.txt
      
      These changes to the trunk are for setting up a trunk repository so that it has all the files and directories that are needed for the Specifics tutorial section.
      ------------------------------------------------------------------------
      r35 | $LOGNAME | 2016-02-06 16:45:40 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/etc
      
      Adding the pin/ directory.
      ------------------------------------------------------------------------
      r34 | $LOGNAME | 2016-02-06 16:45:39 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/lib/readme_only.py
      
      Change made to correct the properties on readme_only.py using propdel svn:executable
      ------------------------------------------------------------------------
      r33 | $LOGNAME | 2016-02-06 16:45:39 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/ever_growing_file.dat
      
      Change made to provide a .dat file that we would want to ignore using propset svn:ignore
      ------------------------------------------------------------------------
      r32 | $LOGNAME | 2016-02-06 16:45:39 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics/lib
         A /specifics/lib/my_hello_script.py
      
      Change made to correct the properties on my_hello_script.py using propset svn:executable ON
      ------------------------------------------------------------------------
      r30 | $LOGNAME | 2016-02-06 16:45:38 +0000 (Sat, 06 Feb 2016) | 1 line
      Changed paths:
         A /specifics
      
      New folder specifics
      ------------------------------------------------------------------------
      
      
      

    Here we want to only merge in the adding of the etc/ directory and "Rock" commits 1 and 2.

    How do you think we can merge just these changes using the command above?

      
      cd ~/my_fcm_tutorial/specifics
      fcm sw fcm:fcm_sp/branches/dev/${LOGNAME}/r36_branch_merge_custom
      fcm merge --custom --revision 48:52 fcm:fcm_sp_br/dev/$LOGNAME/r36_branch_merge_custom2
      
      -------------------------------------------------------------------------dry-run
      --- Merging r48 through r52 into '.':
      A    etc
      A    etc/amazing_rock.txt
      -------------------------------------------------------------------------dry-run
      Would you like to go ahead with the merge?
      Enter "y" or "n" (or just press <return> for "n"): y
      Merge succeeded.
      --------------------------------------------------------------------------actual
      --- Merging r48 through r52 into '.':
      A    etc
      A    etc/amazing_rock.txt
      --- Recording mergeinfo for merge of r48 through r52 into '.':
       U   .
      --------------------------------------------------------------------------actual
      
      
      

  3. fcm merge --custom URL1@REV1 URL2@REV2 This is custom merge using the delta between the two specified branch URLs. For each URL, if a revision is not specified, the command will use the URL with the last changed revision.
  4. We want to only merge in the Rock commit 3.

    How do you think we can do this using the command above?

      
      fcm merge --custom fcm:fcm_sp_br/dev/$LOGNAME/r36_branch_merge_custom2@53 fcm:fcm_sp_br/dev/$LOGNAME/r36_branch_merge_custom2@54
      
      merge: status of ".":
       M      .
      A  +    etc
      merge: continue?
      Enter "y" or "n" (or just press <return> for "n"): y
      -------------------------------------------------------------------------dry-run
      --- Merging r54 into '.':
      U    etc/amazing_rock.txt
      -------------------------------------------------------------------------dry-run
      Would you like to go ahead with the merge?
      Enter "y" or "n" (or just press <return> for "n"): y
      Merge succeeded.
      --------------------------------------------------------------------------actual
      --- Merging r54 into '.':
      U    etc/amazing_rock.txt
      --- Recording mergeinfo for merge of r562 into '.':
       G   .
      --------------------------------------------------------------------------actual
      
      
      

fcm propset svn:execuatable

We have added a file without changing the permissions on that file before committing it back to the repository.

The next time that this file is checked out it will not have the permissions that we require.

We can change the permissions to executable by using:

fcm propset|pset|ps svn:execuatable ON <FILENAME>

Next time that we commit changes to the repository it will change the file permissions on that file.

cd ~/my_fcm_tutorial/specifics
fcm sw fcm:fcm_sp/branches/dev/${LOGNAME}/r36_branch_propset_exe
cd lib
ls -ltr

total 4
-rw-r--r-- 1 $LOGNAME users 41 Feb  2 16:42 my_hello_script.py
-rwxr-xr-x 1 $LOGNAME users 72 Feb  2 16:42 readme_only.py

# Note "my_script.py" does not have executable on it.
# We need to change this so when it is checkout again the permission are 
# correct.
fcm ps svn:executable ON my_hello_script.py
ls -ltr

total 4
-rwxr-xr-x 1 $LOGNAME users 41 Feb  2 16:42 my_hello_script.py
-rwxr-xr-x 1 $LOGNAME users 72 Feb  2 16:42 readme_only.py

# Make another change to the repository, add another python script but set the
# permissions correct before we commit it to the repository.
cat > my_goodbye_script.py << EOF
/usr/bin/env python
print 'Goodbye for now'
EOF
chmod 755 my_goodbye_script.py
# Check the status of the branch
fcm st

?       my_goodbye_script.py
 M      my_hello_script.py

What do the returned statuses mean and what action if any do you need to take?

    '?' means it is not under version control so we must add it.

    fcm add my_goodbye_script.py

    ' M' means the properties are modified and no action is needed by us.

fcm ci

[info] vi: starting commit message editor...
Change summary:
--------------------------------------------------------------------------------
[Root   : file:///$HOME/fcm_tutorial/repository]
[Project: specifics]
[Branch : branches/dev/$LOGNAME/r36_branch_propset_exe]
[Sub-dir: ]

A       lib/my_goodbye_script.py
 M      lib/my_hello_script.py
--------------------------------------------------------------------------------
Commit message is as follows:
--------------------------------------------------------------------------------
Changed the properties of lib/my_hello_script.py and added a new script.
--------------------------------------------------------------------------------
Would you like to commit this change?
Enter "y" or "n" (or just press <return> for "n"): y
Adding         lib/my_goodbye_script.py
Sending        lib/my_hello_script.py
Transmitting file data .
Committed revision 56.
Updating '.':
At revision 56.

Now we have changed the executable properties on the my_hello_script.py script.

If we checked in/committed the branch it would have the correct properties. Note that as the trunk has the wrong properties for my_hello_script.py then all of the other branches created from it will have the wrong properties.

We should merge our change into the trunk to correct this. Do this now.

fcm propset svn:ignore

We want to ignore a file in the repository that we are working on as the file is needed but is not to be associated with the repository as it is very big or we keep updating it.

fcm propset|ps svn:ignore <FILENAME> .

cd ~/my_fcm_tutorial/specifics
fcm sw fcm:fcm_sp/branches/dev/r36_branch_propset_ign
# export SVN_EDITOR='gvim -f'
fcm st
fcm ps svn:ignore "ever_growing_file.dat" .
fcm st

 M      .

# Note the dot at the end of the line. It tells SVN that the property is being set on the current directory.

FCM will now ignore the file ever_growing_file.dat.

We can check this using:

fcm propget svn:ignore .

ever_growing_file.dat


This show us the list of the files at are being ignored in the current directory.

fcm propdel svn:execuatable

We can remove the executable permissions on a file by:

fcm propdel|pdel|pd svn:executable <FILENAME>

Next time that we commit changes to the repository it will change the file permissions on that file.

cd ~/my_fcm_tutorial/specifics
fcm sw fcm:fcm_sp/branches/dev/${LOGNAME}/r36_branch_propdel/lib
ls -ltr

total 4
-rw-r--r-- 1 $LOGNAME users 41 Feb  2 16:42 my_hello_script.py
-rwxr-xr-x 1 $LOGNAME users 72 Feb  2 16:42 readme_only.py

# Note "readme_only.py" has executable on it and it should be read only.
# We need to change this so when it is checkout again the permission are
# correct.
fcm pd svn:executable readme_only.py

property 'svn:executable' deleted from 'readme_only.py'.

ls -ltr

total 4
-rw-r--r-- 1 $LOGNAME users 41 Feb  2 16:42 my_hello_script.py
-rw-r--r-- 1 $LOGNAME users 72 Feb  2 16:42 readme_only.py

# Make another change to the repository, add another python script but set the
# permissions correct before we commit it to the repository.
cat > readme2.py << EOF
/usr/bin/env python
print 'Another readme script.'
EOF

What do we need to do before we commit back to the repository?

    
    fcm st
    
    ?       readme2.py
     M      readme_only.py
    
    # What does the ' M' for readme_only.py mean? See above in fcm propset svn:execuatable
    fcm add readme2.py
    fcm ci
    
    /net/$HOME/my_fcm_tutorial/specifics/branch_propde: working directory changed to top of working copy.
    [info] gvim -f: starting commit message editor...
    Change summary:
    --------------------------------------------------------------------------------
    [Root   : file:///$HOME/fcm_tutorial/repository]
    [Project: specifics]
    [Branch : branches/dev/$LOGNAME/r36_branch_propde]
    [Sub-dir: ]
    
    A       lib/readme2.py
     M      lib/readme_only.py
    --------------------------------------------------------------------------------
    Commit message is as follows:
    --------------------------------------------------------------------------------
    Changed the properties of lib/readme_only.py and lib/added readm2.py.
    --------------------------------------------------------------------------------
    Would you like to commit this change?
    Enter "y" or "n" (or just press <return> for "n"): y
    Adding         lib/readme2.py
    Sending        lib/readme_only.py
    Transmitting file data .
    Committed revision 56.
    Updating '.':
    At revision 56.
    
                                    
                                        
                               

Now we have changed the executable properties on the readme_only.py script.

If we checked in/committed the branch it would have the correct properties. Note that as the trunk has the wrong properties for readme_only.py then all of the other branches created from it will have the wrong properties.

We should merge our change into the trunk to correct this.

propedit svn:log

We want to change a log entry as we made a mistake in it.

The general view is not to worry too much and to add a correction comment in the next commit message.

However, we can change it using/with:

fcm propedit|pedit|pe svn:log --revprop -r <REVISION> fcm:<KEYWORD>

fcm pe svn:log --revprop -r <REVISION> <URL> or

fcm pe svn:log --revprop -r <REVISION> <BRANCH_URL>

cd ~/my_fcm_tutorial/specifics
fcm sw fcm:fcm_sp/branches/dev/${LOGNAME}/r36_branch_propedit

One of the log commits has a typo. How can we find the typo?

    fcm log
    
    ------------------------------------------------------------------------
    r41 | $LOGNAME | 2016-02-02 16:42:30 +0000 (Tue, 02 Feb 2016) | 1 line
    
    Made a branch Created file:///$HOME/fcm_tutorial/repository/specifics/branches/dev/$LOGNAME/r36_branch_propedit from /trunk@31.
    ------------------------------------------------------------------------
    r36 | $LOGNAME | 2016-02-02 16:42:29 +0000 (Tue, 02 Feb 2016) | 1 line
    
    These changes to the trunk are for setting up a trunk repository so that it has all the files and directories that are needed for the Specifics tutorial section.
    ------------------------------------------------------------------------
    r35 | $LOGNAME | 2016-02-02 16:42:28 +0000 (Tue, 02 Feb 2016) | 1 line
    
    Adding the etd/ directory.
    ------------------------------------------------------------------------
    r34 |i $LOGNAME | 2016-02-02 16:42:27 +0000 (Tue, 02 Feb 2016) | 1 line
    
    Change made to correct the properties on readme_only.py using propdel svn:executable
    ------------------------------------------------------------------------
    r33 | $LOGNAME | 2016-02-02 16:42:27 +0000 (Tue, 02 Feb 2016) | 1 line
    
    Change made to provide a .dat file that we would want to ignore using propset svn:ignore
    ------------------------------------------------------------------------
    r32 | $LOGNAME | 2016-02-02 16:42:27 +0000 (Tue, 02 Feb 2016) | 1 line
    
    Change made to correct the properties on my_hello_script.py using propset svn:executable ON
    ------------------------------------------------------------------------
    r30 | $LOGNAME | 2016-02-02 16:42:25 +0000 (Tue, 02 Feb 2016) | 1 line
    
    New folder specifics/trunk
    ------------------------------------------------------------------------
    
    
    r35, "etd/" should be "/etc"

Now we can correct it.

export SVN_EDITOR="gvim"
fcm pe svn:log --revprop -r 35 fcm:fcm_sp_br/dev/${LOGNAME}/r36_branch_propedit

Set new value for property 'svn:log' on revision 35

This will correct the log message in the commit.

General about Trac and Tickets

Here we will cover the minimum information that is needed to understand Trac and Tickets.

Trac

Trac is a wiki system which we can use for organizing knowledge and information in a very flexible way that FCM has be designed to interact with. A brief summary on Trac:

fcm browse

If setup correctly on your site we can invoke the web-browser to launch the corresponding URL of the web-based repository browser (currently Trac browser). fcm browse|trac|www <URL>

branch-diff -t

We can launch Trac with the default web browser to report the diff of a branch using: fcm branch-diff --trac|-t <URL|local/working copy>

Tickets

Tickets allow people to follow an issue, or a list of tickets matching the chosen criterion. Creating a ticket

Text conflicts

In Essentials tutorial III text conflicts we created a text conflict and resolved it.

The text conflict was created by?

  • Creating two branches from the trunk and checking them out with different names.
  • In "branch1" we appended to a text file some additional text. We then committed the change.
  • In "branch2" we appended to a text file of the same name as in "branch1" some different additional text. We then committed the change.
  • We then merged "branch1" into "branch2". This created a Text conflict.

fcm st returns the following when there is a text conflict on the repository:

C    statusesC_text.txt 

How did we resolve the text conflict?

    fcm conflicts Left clicked on the text option that we want to keep.

    Then press "m", or use the toolbar; File -> Exit with MERGED M to merge the change.

Now we need to learn more about the command fcm conflicts.

conflicts

The command fcm conflicts|cf is a graphical tool to help resolve conflicts within the local/working copy. Note it cannot help with all conflicts. It works with the most effectively with Text Conflicts.

A type of conflict that we may come across are "Text conflicts". These are returned via fcm st as

C    statusesC_text.txt 

where column 1 has a "C" in it.

To resolve the text conflict we use the 3-way difference tool xxdiff.

For each file with a text conflict, the fcm conflicts command calls a graphical merge tool (i.e. xxdiff by default) to display a 3-way diff.

How to use xxdiff to help resolve text conflicts

The file on the left is our original file. The file in the middle is the common ancestor from the merge. The file on the right is the file containing the changes which we are merging in.

A quick way of resolving the conflict (from Essentials tutorial III text conflicts):

    fcm cf screengrab

    # Left click on the text option that we want to keep, it should change colour from yellow to purple.

    # Then press "m", or use the toolbar; File -> Exit with MERGED M.

Explanations of the three window split xxdiff:

The number on the far right panel of xxdiff tool is the number of unselected differences, known as "hunks" or "sections" and they are often seen in yellow. The correct term for the highlighted section is hunk, but here we will refer to it as the section as it is easier to understand and remember what we are talking about.

When this number is 0 then we are ready to save the merged file.

To see how the merged file will look with the current selections, click Windows->Toggle Merged View (keyboard shortcut: Alt+Y).

An extra window then appears showing the merged output that updates interactively as we make our selections.

Useful xxdiff keyboard shortcuts:

Everyday language:

p - previous change

n - next change

o - previous conflict

b - next conflict

m - accept merge the section that is left clicked on and exit.

a - accept and exit.

m - reject and exit.

FCM/correct language:

B - move to the next unselected section

O - move to the previous unselected section

To exit the 3-way diff (available from the File menu):

Exit with MERGE (keyboard shortcut: M)

Exit with ACCEPT (keyboard shortcut: A)

Exit with REJECT (keyboard shortcut: R)

If we just want to exit without making any decisions we can also just close the window.

xxdiff documentation

If we have resolved all the conflicts in a file then we will be prompted on whether to run svn resolved on the file to signal that the file is no longer in conflict.

fcm conflicts
Conflicts in file: statusesC_text.txt
You have chosen to ACCEPT all the changes
Would you like to run "svn resolved"?
Enter "y" or "n" (or just press  for "n"): y
Resolved conflicted state of 'statusesC_text.txt'

Here we only had one file with one small conflict.

If we have 2 versions of a file, both with substantial changes, then the xxdiff display will be extremely colourful but very helpful.

In these cases it is often easier to start with one version of the file and manually re-apply the changes from the other version.

It might not be obvious how to do this and we may need to speak to the author of the other change to agree how to correctly combine the change.

Fortunately this situation should be very rare.

resolve

The fcm resolve command can be used to resolve conflicts in local/working copy files or directories.

A common way of using this command is:

fcm resolve --accept working <FILENAME>

cd ~/my_fcm_tutorial/specifics
fcm sw fcm:fcm_sp/branches/dev/${LOGNAME}/r36_branch_resolve
fcm bls

[info] fcm:fcm_sp@78: 9 match(es)
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_conflict_tree@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_conflict_tree2@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_merge_custom@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_merge_custom2@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_propdel@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_propedit@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_propset_exe@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_propset_ign@78
fcm:fcm_sp/branches/dev/$LOGNAME/r36_branch_resolve@78

fcm merge fcm:fcm_sp_br/dev/$LOGNAME/branch_conflict_tree

Eligible merge(s) from /specifics/branches/dev/$LOGNAME/r36_branch_conflict_tree@78: 46 45
Enter a revision (or just press <return> for "46"): 
--------------------------------------------------------------------------------
Merge: /specifics/branches/dev/$LOGNAME/r36_branch_conflict_tree@46
 c.f.: /specifics/trunk@643
-------------------------------------------------------------------------dry-run
--- Merging r44 through r46 into '.':
   C lib/utility
   A lib/utility/tool_list.txt
D    tree_conflict.txt
Summary of conflicts:
  Tree conflicts: 1
-------------------------------------------------------------------------dry-run
Would you like to go ahead with the merge?
Enter "y" or "n" (or just press <return> for "n"): y
Merge succeeded.
--------------------------------------------------------------------------actual
--- Recording mergeinfo for merge of r42 through r43 into '.':
 U   .
--- Merging r44 through r46 into '.':
   C lib/utility
   A lib/utility/tool_list.txt
D    tree_conflict.txt
--- Recording mergeinfo for merge of r44 through r46 into '.':
 U   lib/utility/tool_list.txt
 G   .
Summary of conflicts:
  Tree conflicts: 1
--------------------------------------------------------------------------actual

fcm st

 M      .
      C lib/utility
      >   local dir obstruction, incoming dir add upon merge
 M      lib/utility/tool_list.txt
D       tree_conflict.txt
Summary of conflicts:
  Tree conflicts: 1

fcm resolve --accept working lib/utility

Resolved conflicted state of 'lib/utility'

The conflict has been resolved.

We will use this command further in the conflicts section and scroll down to the tree conflict sub-section.

Tree conflicts

Tree conflict, which are otherwise known as a structural or filesystem-based conflicts.

These can be more complicated than text conflicts.

fcm st returns the following when there is a tree conflict on the repository, indicated by a "C" present in column 7 of the returned output:

       C lib/utility/my_tools

fcm conflicts should manually resolve the problem by prompting us to choose a course of action. We can either keep the file as it was before the merge (keeping the local copy), or accept the external changes to the file.

FCM has issues when the same directory or file has been added to two separate branches. The problem can occur when merging two branches that both have the same directory or file added. E.g. JoeBloggs added lib/utility/my_tool to a branch and we also added the same directory or file. Assuming that both add exactly the same directories or files then running the following command in our local/working copy should get around this problem.

fcm resolve --accept working lib/utility/my_tools

As we used above in the resolve sub-section.

A common way to generate a tree conflict after a merge is when a file has been deleted or renamed on one branch, and modified on another. These are incompatible changes, therefore Subversion doesn't know which action to take. This is the cause of the tree conflict dilemma which the user must solve.

cd ~/my_fcm_tutorial/specifics
fcm sw fcm:fcm_sp/branches/dev/${LOGNAME}/r36_branch_conflict_tree
fcm up
# The file tree_conflict.txt has been deleted from it.
# Merge in branch_conflict_tree2 which has a modification to tree_conflict.txt

fcm merge fcm:fcm_sp_br/dev/$LOGNAME/branch_conflict_tree2

Accept the merge.


Eligible merge(s) from /specifics/branches/dev/$LOGNAME/r36_branch_conflict_tree2@78: 48
--------------------------------------------------------------------------------
Merge: /specifics/branches/dev/$LOGNAME/r36_branch_conflict_tree2@48
 c.f.: /specifics/trunk@643
-------------------------------------------------------------------------dry-run
--- Merging r47 through r48 into '.':
   C tree_conflict.txt
Summary of conflicts:
  Tree conflicts: 1
-------------------------------------------------------------------------dry-run
Would you like to go ahead with the merge?
Enter "y" or "n" (or just press <return> for "n"): y
Merge succeeded.
--------------------------------------------------------------------------actual
--- Recording mergeinfo for merge of r44 through r46 into '.':
 U   .
--- Merging r47 through r48 into '.':
   C tree_conflict.txt
--- Recording mergeinfo for merge of r47 through r48 into '.':
 G   .
Summary of conflicts:
  Tree conflicts: 1
--------------------------------------------------------------------------actual

How can we try to resolve the conflict?


fcm conflicts
# choose to keep the local version or not.


[info] tree_conflict.txt: in tree conflict.
Locally: deleted.
Externally: edited.
Answer (y) to accept the local delete.
Answer (n) to keep the file.
Keep the local version?
Enter "y" or "n" (or just press <return> for "n") y
Resolved conflicted state of 'tree_conflict.txt'

In this example, to keep the file as it was before (in a deleted state), enter y.

Otherwise, to accept the merge branch version of the file (adding it with the edited changes), enter n.

fcm conflicts does not cover tree conflicts on directories because of the potential nesting of conflicts within the directories.

We have already covered an example of this above in the resolve sub-section.

Note, it can often be difficult to identify the problem and figure out the solution in the case of directory conflicts, and the easiest solution may be to try to resolve the discrepancy before the merge.

Use fcm st to find out if the tree conflict has arisen from a rename. A rename can have occurred locally or externally. An external rename would show up in fcm status as an addition with history (A with +): for example:


A   +   FILENAME

Now we can use fcm log -v <FILENAME> to examine if this is really just a rename then it will show up as FILENAME (from ORIGINAL_FILENAME).

Warning, local renames that have been committed won't show up in fcm status. However, these can still be found using fcm log -v for each filename.

tree conflicts resolution list

Commands to use to help with resolving tree conflicts:
fcm st
fcm log -v <FILENAME>
fcm resolve --accept working <FILENAME>
fcm help <COMMAND>

local add, incoming add upon merge

local edit, incoming delete upon merge (no renaming)

local edit, incoming delete upon merge (renaming)

local delete, incoming delete upon merge (no renaming)

local delete, incoming delete upon merge (just external renaming)

local delete, incoming delete upon merge (just local renaming)

local delete, incoming delete upon merge (local renaming AND external renaming)

local missing, incoming edit upon merge (no renaming)

local missing, incoming edit upon merge (renaming)

local missing, incoming edit upon merge (renaming)

A final resort or a simpler solution: checkout a new working/local copy of the trunk/branch or create a new branch from the trunk/branch and apply your changes using best working practices and only making one or a few changes at a time, committing the changes to your branch and merging to the trunk only a few changes at a time.

fcm make

fcm make is not covered in this tutorial.

Please refer to the fcm make pages.

cherry pick

There is no support for cherry picking from a branch in FCM.

If you decide to try to do this then there will be no user support.

Congratulations you have completed the FCM tutorial!

Don't forget to remove the repository if it is not needed anymore or if you wish to do the repository again in the future. rm -rf ~/fcm_tutorial; rm -rf ~my_fcm_tutorial

WARNING: this is a draft document it is under review awaiting approval and can be removed at any time


© British Crown Copyright 2006-16 Met Office.
This document is released under the British Open Government Licence.