chiark / gitweb /
git-branchmove: new script, still work in progress
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 7 Oct 2015 14:56:28 +0000 (15:56 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 7 Oct 2015 14:56:28 +0000 (15:56 +0100)
scripts/git-branchmove [new file with mode: 0755]

diff --git a/scripts/git-branchmove b/scripts/git-branchmove
new file mode 100755 (executable)
index 0000000..49fd370
--- /dev/null
@@ -0,0 +1,77 @@
+#!/bin/bash
+#
+# Moves a branch to or from the current git tree to or from
+# another git tree
+#
+# usage:   git-branchmove get|put REMOTE BRANCH
+
+set -e
+set -o posix
+
+fail () { echo >&2 "git-branchmove: $*"; exit 16; }
+badusage () { fail "bad usage: $*"; }
+
+case "$#.$1" in
+3.get)
+       op=get
+       remote="$2"
+       branch="$3"
+       ;;
+3.put)
+       op=put
+       branch="$3"
+       ;;
+*)
+       badusage "wrong number of arguments or wrong operation"
+       ;;
+esac
+
+# Plan of attack:
+#  determine execute-sh runes for src and dst trees
+#  check that source branch is not checked out
+#  list affected branches on source
+#  list affected branches on destination and moan if any nonequal overlap
+#  transfer src->dst refs/heads/BRANCH:refs/heads/BRANCH
+#  transfer and merge reflog(s) xxx todo
+#  delete src refs
+
+case "$remote" in
+*:*)   remoteurl="$remote" ;;
+*)     remoteurl="$(
+               git config remote."$remote".pushurl ||
+               git config remote."$remote".url ||
+               fail "no pushurl or url defined for remote $remote"
+               )"
+esac
+
+remote_spec="$(perl -e '
+    $_ = $ARGV[0];
+    if (m#^ssh://([^:/]+)(?:\:(\w+))?#) {
+       print "$'\''|ssh ";
+       print " -p $3" if $2;
+        print "$1\n";
+    } elsif (m#^([-+_.0-9a-zA-Z\@]+):(?!//)#) {
+        print "$'\''|ssh $1\n";
+    } else {
+        die "git-branchmove: unsupported remote url \`$_'\''\n";
+    }
+' "$remoteurl")"
+
+remote_path="${remote_spec%%|*}"
+remote_rune="${remote_spec#*|}"
+
+case $op in
+get)
+       src_rune="$remote_rune"
+       src_path="$remote_path"
+       dst_rune="sh -c"
+       dst_path=.
+       ;;
+put)
+       dst_rune="$remote_rune"
+       dst_path="$remote_path"
+       src_rune="sh -c"
+       src_path=.
+       ;;
+esac
+