#!/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 #dry_run=: dry_run=false cmd() { echo "CMD>" "$@" "$dry_run" || "$@" } gf_init() { echo "$self: Examining configuration" config_found=no for configvar in "rebase-subtree.rebase" "rebase-subtree.subtree" do if test -n "$(git config --get-all "$configvar")" then if test "x$configvar" = "xrebase-subtree.subtree"; then echo "$self: WARNING: Using deprecated config variable rebase-subtree.subtree." echo " Better use rebase-subtree.rebase lines instead." fi git config --get-all "$configvar" | 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 config_found=yes break fi done test "x$config_found" = "xyes" || die "Unset or empty git config var \"rebase-subtree.rebase\"" } 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() { reverse="no" case "$1" in --reverse) reverse=yes; shift ;; esac newroot="$1" test "x$newroot" = "x" && die "Need parameter" oldroot="$2" test "x$oldroot" = "x" && die "Need parameter" echo echo "CAUTION: ${self} does not handle merge errors yet - that will mess up your repo!" echo "Press Ctrl-C to abort. Or, if you feel adventurous, press ENTER." read echo echo "$self: Preparing subtree rebase" git config --get-all "$configvar" | 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 echo echo "$self: Executing subtree rebase" git config --get-all "$configvar" | while read from to restofline; do if test "x#" = "x$(echo "$from" | sed -n '1s/^\(.\).*/\1/p')"; then continue; fi if test "x$reverse" = "xno" && test "x$from" = "x$oldroot"; then cmd git-rebase "$newroot" "$oldroot" cmd git-rebase --onto "$newroot" "follow-old/$from" "$to" elif test "x$reverse" = "xyes" && test "x$from" = "x$newroot"; then cmd git-rebase --onto "$newroot" "$oldroot" "$to" else cmd git-rebase --onto "$from" "follow-old/$from" "$to" fi done echo echo "$self: Cleaning up after subtree rebase" git config --get-all "$configvar" | 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 } gf_init gf_rebase_tree "$@" # End of file.