#!/bin/bash SUBDIRECTORY_OK=Yes OPTIONS_SPEC= . git-sh-setup require_work_tree cd_to_toplevel DATE="$(date +'%Y%m%d_%H%M%S')" USE_COLORS="yes" usage () { echo "Usage: $(basename $0) [-C] [-c] [-m message]" exit 1 } info () { if [ "x$USE_COLORS" == "xyes" ]; then echo -en "\033[32m" fi echo -n "** " if [ "x$USE_COLORS" == "xyes" ]; then echo -en "\033[0m" fi echo "$@" } error () { if [ "x$USE_COLORS" == "xyes" ]; then echo -en "\033[31m" fi echo -n "!! " if [ "x$USE_COLORS" == "xyes" ]; then echo -en "\033[0m" fi echo "$@" exit 1 } main () { commit_message="" temporary_branch="svn.merge.$DATE" verbose="no" while getopts "hCm:v" opt; do case "$opt" in C) USE_COLORS="no" ;; v) verbose="yes" ;; m) commit_message="$OPTARG" ;; *) usage ;; esac done shift $((OPTIND - 1)) # attempt a rebase against the latest revision in subversion [ "$verbose" == "yes" ] && info "attempting to rebase" git svn rebase >/dev/null 2>&1 || error "rebase failed: this is probably due to conflicts" # determine the active branch, the checksum of the most recent # dcommit to subversion, and the checksom of HEAD active_branch="$(git branch --no-color | awk '/^[*]\s*/ { print $0 }' | sed -e 's/^[*]\s//g')" last_dcommit_revision="$(git svn info | awk '/^Revision:\s*/ { print $0; }' | sed -e 's/^Revision:\s*//g')" [ -z $last_dcommit_revision ] && error "could not determine most recent dcommit" last_dcommit="$(git svn find-rev r$last_dcommit_revision)" [ -z $last_dcommit ] && error "could not determine most recent dcommit" last_revision="$(git rev-parse HEAD)" [ -z $last_revision ] && error "could not determine HEAD checksum" # has anything changed from our last subversion commit? if [ "x$last_dcommit" == "x$last_revision" ]; then [ "$verbose" == "yes" ] && info "no local changes to $active_branch" exit 0 fi # create a temporary branch for merging our local changes [ "$verbose" == "yes" ] && info "creating temporary branch for merging" git branch "$temporary_branch" >/dev/null 2>&1 || error "could not create temporary branch" # wind the active branch back to the most recent dcommit [ "$verbose" == "yes" ] && info "resetting $active_branch to $last_dcommit" git reset --hard "$last_dcommit" >/dev/null 2>&1 || error "reset to $last_dcommit failed" # merge the changes from the temporary branch into the active branch [ "$verbose" == "yes" ] && info "merging with $temporary_branch" merge_opts=(--no-ff) if [ ! -z "$commit_message" ]; then merge_opts=(${merge_opts[@]} --no-summary "-m $commit_message") fi git merge "${merge_opts[@]}" "$temporary_branch" || error "could not merge with $temporary_branch" [ "$verbose" == "yes" ] && info "merge complete: local changes merged into $active_branch" } main "$@"