#!/bin/sh # git-rebase-subtree - rebase "subtree of branches" in one go # Copyright (C) 2007 Hans Ulrich Niedermann # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA unset CDPATH SED="${SED-sed}" self=`basename "$0"` selfdir=`dirname "$0"` selfdir=`cd "$selfdir" && pwd` . "$selfdir/git-ndim-sh" SUBDIRECTORY_OK="yes" USAGE=" [params...]" LONG_USAGE="\ Let a local subtree of branches follow a remote origin without too much merging. For more details, see the ${self}(1) man page." . git-sh-setup require_work_tree # Abort on error set -e cmd() { echo "CMD>" "$@" gitk --all "$@" } gf_init() { echo "$self: Examining configuration" git config follow.tree | while read from to restofline; do if test "x#" = "x$(echo "$from" | sed -n '1s/^\(.\).*/\1/p')"; then continue; fi echo "" echo " From: $from" echo " To: $to" done } gf_branch() { branch="$1" newbranch="follow-old/$branch" if git-rev-parse --verify "$branch" > /dev/null 2>&1; then # valid branch if git-rev-parse --verify "$newbranch" > /dev/null 2>&1; then : # branch already exists, do nothing else cmd git-branch "${newbranch}" "${branch}" fi else echo "$self: gf_branch called with invalid branch \"$branch\"" >&2 exit 1 fi } gf_rmbranch() { branch="$1" newbranch="follow-old/$branch" if git-rev-parse --verify "$branch" > /dev/null 2>&1; then if git-rev-parse --verify "$newbranch" > /dev/null 2>&1; then cmd git-branch -D "${newbranch}" fi fi } gf_rebase_tree() { newroot="$1" test "x$newroot" = "x" && die "Need parameter" oldroot="$2" test "x$oldroot" = "x" && die "Need parameter" echo echo "$self: Preparing subtree rebase" git config follow.tree | while read from to restofline; do if test "x#" = "x$(echo "$from" | sed -n '1s/^\(.\).*/\1/p')"; then continue; fi gf_branch "$from" gf_branch "$to" done gitk --all echo echo "$self: Executing subtree rebase" git config follow.tree | while read from to restofline; do if test "x#" = "x$(echo "$from" | sed -n '1s/^\(.\).*/\1/p')"; then continue; fi cmd git-rebase --onto "$from" "follow-old/$from" "$to" done gitk --all echo echo "$self: Cleaning up after subtree rebase" git config follow.tree | while read from to restofline; do if test "x#" = "x$(echo "$from" | sed -n '1s/^\(.\).*/\1/p')"; then continue; fi gf_rmbranch "$from" gf_rmbranch "$to" done gitk --all } # The great command case command="$1" if shift; then case "$command" in rebase-subtree) gf_init gf_rebase_tree "$@" ;; *) die "Invalid command line parameter: \"$command\"" ;; esac else gf_init fi # End of file.