#!/bin/sh # vim: foldmethod=marker # DJANGO GIT UPDATING SCRIPT, PLEASE READ THOSE INSTRUCTIONS. # This script expects you to have the following structure: # * Some branches that match the $TRUNK regex which are *clean* # copies of SVN trunk or branches. # * A master branch coming from every of those $TRUNK branches, aka: master # * Any other topic branches will pull from one of those masters (or not) # The script expects the "pull" configuration to be set correctly for every branch. # Imagine the following scenarios: # * A master branch follows trunk: # git config branch.master.remote . # git config branch.master.merge trunk # * A master-1.0.X branch follows trunk-1.0.X # git config branch.master-1.0.X.remote . # git config branch.master-1.0.X.merge trunk-1.0.X # * A 6735-views branch that follows master # git config branch.6735-views.remote . # git config branch.6735-views.merge master # By doing this configuration you tell git where to merge from when running # "git pull" on a branch. # If you wonder how to setup GIT to understand Django's SVN structure ask Marc Fargas # at telenieko@telenieko.com # Base directory of you django git repo. DJANGO=$HOME/dev/python/django # Regex to find local branches that represent *clean* copies of svn trunk or branches. # We will run "git svn rebase" on this branch, and then pull from those. # NEVER PUBLISH THOSE BRANCHES ON THE INTERNET. THANKS. TRUNK="trunk.*" # Regex to find the "master" branches, those are the ones that pull from $TRUNK # and are never rebased so can be published safely. MASTER="master.*" # Regex of branches to ignore, in case you have some branches you # do not want to automatically update. IGNORE='private/.*' ## CONFIG END ## DIR=`pwd` # What branches do we have? cd $DJANGO/.git/refs/heads BRANCHES=`find -type f` cd $DJANGO # {{{ match_branch: Check if the branch in $1 matches the regex in $2 # Takes the branch name as $1, and the ignore list as $2 # Return value 0 if no match # Return value 1 if matches match_branch() { br=$1 ignore=$2 if [ `expr match "$br" "$ignore"` -gt 0 ]; then return 1 elif [ "$br" = "=" ]; then return 1 fi return 0 } # }}} # {{{ ignore_branch: Check if the branch in $1 has to be ignored # (aka: not in $TRUNK, $MASTER, $IGNORE # Takes the branch name as $1 # Return value 0 if ok. # Return value 1 if should be ignored. ignore_branch() { br=$1 if [ `expr match "$br" "$TRUNK"` -gt 0 ]; then return 1 elif [ `expr match "$br" "$MASTER"` -gt 0 ]; then return 1 elif [ `expr match "$br" "$IGNORE"` -gt 0 ]; then return 1 fi return 0 } # }}} # {{{ update_branch: Merge, from branch $1 the branch $MASTER. # On failure we "git reset --hard", print a message and return 1. update_branch() { echo "Merging $1 with its master" git checkout $1 git pull RES=$? if ! [ $RES -eq 0 ] then echo "MERGE FAILED FOR $1 DO IT BY HAND" git reset --hard echo "MERGE FAILED FOR $1 DO IT BY HAND" return 1 fi } # }}} # {{{ update_svn: Update our $TRUNK branches with code from svn. # That runs "svn fetch", "svn rebase" and merges $TRUNK into $MASTER. update_svn() { cd $DJANGO git svn fetch for BR in $BRANCHES do BR=${BR:2} match_branch $BR $TRUNK RES=$? if [ $RES -eq 1 ] then echo "Merging $BR with SVN" git checkout $BR git svn rebase RES=$? if ! [ $RES -eq 0 ] then echo "COULD NOT MERGE $BR" return 1 fi fi done } # }}} # {{{ update_master: Update our $MASTER branches with code from our $TRUNK. # That runs "git pull" on those branches. update_master() { cd $DJANGO for BR in $BRANCHES do BR=${BR:2} match_branch $BR $MASTER RES=$? if [ $RES -eq 1 ] then echo "Merging $BR with trunk branch" git checkout $BR git pull RES=$? if ! [ $RES -eq 0 ] then echo "COULD NOT MERGE $BR" return 1 fi fi done } # }}} update_svn RES=$? if ! [ $RES -eq 0 ]; then echo "Got trouble updating svn, aborting." cd $DIR ; exit 1 fi update_master RES=$? if ! [ $RES -eq 0 ]; then echo "Got trouble updating master branches, aborting." cd $DIR ; exit 1 fi for BR in $BRANCHES do BR=${BR:2} ignore_branch $BR RES=$? if [ $RES -eq 0 ] then update_branch $BR else echo "Not merging $BR with anyone." fi done # Go back to the directory we were before running. cd $DIR