Changes between Version 18 and Version 19 of MercurialBranches


Ignore:
Timestamp:
07/02/2011 12:37:16 PM (4 years ago)
Author:
lukeplant
Comment:

Updated backport script for features available in Mercurial 1.9

Legend:

Unmodified
Added
Removed
Modified
  • MercurialBranches

    v18 v19  
    2828 * Alternatively, use the [http://mercurial.selenic.com/wiki/MqExtension queues] extension to manage long lived patches.
    2929 * To collapse several commits into a single commit before pushing back to svn, use the [http://mercurial.selenic.com/wiki/HisteditExtension histedit] extension
    30  * To backport a changeset from trunk, use the [http://mercurial.selenic.com/wiki/TransplantExtension transplant] extension.  Or use this handy script which will generate the commit message for you:
    31    {{{
     30
     31=== Backporting ===
     32
     33To backport a changeset from trunk, use the [http://mercurial.selenic.com/wiki/TransplantExtension transplant] extension. From Mercurial 1.9 onwards, you can use the 'filter' feature of transplant to create the commit message for you. Save the following script as ~/bin/django_backport_filter (for example) and make it executable:
     34
     35{{{
    3236#!sh
    33 #!/bin/bash
    34 
    35 function usage {
    36     echo "Usage: hg_backport <branch> <hgrevision>";
    37     echo "   or: hg_backport <branch> --svnrev <svnrevision>";
    38 }
    39 
    40 if [ $# -lt 2 ]
     37#!/bin/sh
     38CURRENT_BRANCH=`hg branch | cut -f 2 -d '/'`
     39SVN_REV=`hg svn info -r $HGREVISION | egrep '^Revision' | cut -f 2 -d ' '`
     40SOURCE_BRANCH=`hg log --template "{branch}" -r $HGREVISION`
     41if [ "x$SOURCE_BRANCH" = "xdefault" ]
    4142then
    42         usage;
    43         exit 1;
     43    SOURCE_BRANCH=trunk
    4444fi
    4545
    46 hg st -a -r -m | grep '' > /dev/null && { echo "Working directory not clean - exiting" > /dev/stderr; exit 1; }
    47 
    48 SHORTBRANCH="$1"
    49 BRANCH="releases/$SHORTBRANCH"
    50 if [ "$2" = "--svnrev" ]
    51 then
    52     SVNREV="$3"
    53     HGREV=`hg log -r "svnrev($SVNREV)" --template '{rev}'`
    54     if [ "x$HGREV" = "x" ]
    55     then
    56         echo "Can't find hg rev"
    57         exit 1;
    58     fi
    59 else
    60     HGREV="$2"
    61     SVNREV=`hg svn info -r $HGREV | egrep '^Revision' | cut -f 2 -d ' '`
    62     if [ "x$SVNREV" = "x" ]
    63     then
    64         echo "Can't find svn rev";
    65         exit 1;
    66     fi
    67 fi
    68 
    69 echo "Backporting Subversion revision $SVNREV"
    70 hg update $BRANCH || exit 1;
    71 # Make a commit message first in case the transplant fails
    72 hg log -r $HGREV --template "[$SHORTBRANCH] {desc}\n\nBackport of [$SVNREV] from trunk.\n" > hg-commit-message.txt || exit 1
    73 hg transplant $HGREV || exit 1;
    74 # Modify the commit message
    75 # We need to get added files, since after rollback this is forgotten
    76 ADDED=$(hg log -r tip --template '{file_adds}')
    77 REMOVED=$(hg log -r tip --template '{file_dels}')
    78 hg rollback > /dev/null || exit 1
    79 if [ "x$ADDED" != "x" ]
    80 then
    81     hg add $ADDED || exit 1
    82 fi
    83 if [ "x$REMOVED" != "x" ]
    84 then
    85     hg remove $REMOVED || exit 1
    86 fi
    87 hg commit -l hg-commit-message.txt || exit 1
    88 echo "Backport committed."
    89    }}}
    90    The command line is like one of the following:
    91    {{{
    92 #!sh
    93 hg_backport 1.2.X 13643
    94 hg_backport 1.2.X --svnrev 13237
    95 }}}
    96    where 1.2.X is a directory under 'releases/' in the Subversion repo, 13643 is a hg revision ID, and 13237 is a Subversion revision ID.  The change is already committed to the local repo, but not 'pushed', so you can still rollback if changes need to be made.
    97 
    98 === An alternate approach ===
    99 
    100 Another way of doing the same thing: Use the --filter option to the transplant extension. This requires the use of a Python script. Put the following in backport.py, and stick it in a tools directory somewhere:
    101 {{{
    102 #!python
    103 #!/usr/bin/python
    104 import os
    105 import sys
    106 
    107 msg = sys.argv[1]
    108 patch = sys.argv[2]
    109 
    110 print
    111 branch = os.environ.get('DJANGO_BRANCH',None)
    112 if branch is None:
    113     branch = raw_input('Backport branch: ')
    114 else:
    115     print "Backport branch:", branch
    116 
    117 msg_file = open(msg, 'r')
    118 outlines = []
    119 firstline = True
    120 for raw_line in msg_file:
    121     line = raw_line.strip()
    122     if firstline:
    123         if line.startswith('#'):
    124             outlines.append(line)
    125         else:
    126             firstline = False
    127             print 'MERGING: %s' % line
    128             outlines.append('[%s] %s' % (branch, line))
    129     else:
    130         outlines.append(line)
    131 msg_file.close()
    132 
    133 svn_revision = os.environ.get('SVNMERGE_REVISION',None)
    134 if svn_revision is None:
    135     svn_revision = raw_input('SVN Revision: ')
    136 else:
    137     print "SVN Revision:", svn_revision
    138 outlines.append('')
    139 outlines.append('Backport of r%s from trunk.' % svn_revision)
    140 
    141 # And write the updated message file.
    142 msg_file = open(msg,'w')
    143 for line in outlines:
    144     print >> msg_file, line
    145 msg_file.close()
    146 
    147 # In case of a clash, write the filename of the message file
    148 print "Log message written to",msg
     46sed -nie '1 p;2 p;3 p' "$1"
     47hg log -r $HGREVISION --template "[$CURRENT_BRANCH] {desc}\n\nBackport of [$SVN_REV] from $SOURCE_BRANCH.\n" >> "$1"
    14948}}}
    15049
    151 Then, use the following shell script to do the actual backport:
     50Then, on the branch you want to backport to:
    15251{{{
    15352#!sh
    154 export SVNMERGE_REVISION=`hg svn info -r $1 | egrep '^Revision' | cut -f 2 -d ' '`
    155 export DJANGO_BRANCH=`hg branch | cut -f 2 -d '/'`
    156 hg transplant $1 --filter /path/to/backport.py
    157 unset SVNMERGE_REVISION
    158 unset DJANGO_BRANCH
     53
     54hg transplant --filter ~/bin/django_backport_filter <hg revision number of changeset to backport>
    15955}}}
    160 
    161 If you call this script 'hg_backport', then
    162 
    163 The command line is like:
    164 {{{
    165 #!sh
    166 hg_backport 13643
    167 }}}
    168 Any hg revision ID can be used as the argument; since the most common usage pattern is to backport the most recent svn commit on trunk, you can use 'tip':
    169 {{{
    170 #!sh
    171 hg_backport tip
    172 }}}
     56(Older revisions of this wiki page have methods that work for older versions of Mercurial, but they are suboptimal - upgrading hg is preferred).
    17357
    17458=== Gotchas ===
Back to Top