From 0ca71b3737cbb26fbf037aa15b3f58735785e6e3 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Fri, 24 Apr 2009 14:13:34 -0400 Subject: [PATCH 1/1] basic options parsing and whatnot. --- .gitignore | 1 + git-subtree | 1 + git-subtree.sh | 123 +++++++++++++++++++++++++++++++++++++++++++++++++ shellopts.sh | 1 + 4 files changed, 126 insertions(+) create mode 100644 .gitignore create mode 120000 git-subtree create mode 100755 git-subtree.sh create mode 100644 shellopts.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b25c15b81 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/git-subtree b/git-subtree new file mode 120000 index 000000000..7d7539894 --- /dev/null +++ b/git-subtree @@ -0,0 +1 @@ +git-subtree.sh \ No newline at end of file diff --git a/git-subtree.sh b/git-subtree.sh new file mode 100755 index 000000000..5e5b27f8a --- /dev/null +++ b/git-subtree.sh @@ -0,0 +1,123 @@ +#!/bin/bash +# +# git-subtree.sh: split/join git repositories in subdirectories of this one +# +# Copyright (c) 2009 Avery Pennarun +# +OPTS_SPEC="\ +git subtree split -- +git subtree merge + +git subtree does foo and bar! +-- +h,help show the help +q quiet +v verbose +" +eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?) +. git-sh-setup +require_work_tree + +quiet= +command= + +debug() +{ + if [ -z "$quiet" ]; then + echo "$@" >&2 + fi +} + +#echo "Options: $*" + +while [ $# -gt 0 ]; do + opt="$1" + shift + case "$opt" in + -q) quiet=1 ;; + --) break ;; + esac +done + +command="$1" +shift +case "$command" in + split|merge) ;; + *) die "Unknown command '$command'" ;; +esac + +revs=$(git rev-parse --default HEAD --revs-only "$@") || exit $? +dirs="$(git rev-parse --sq --no-revs --no-flags "$@")" || exit $? + +#echo "dirs is {$dirs}" +eval $(echo set -- $dirs) +if [ "$#" -ne 1 ]; then + die "Must provide exactly one subtree dir (got $#)" +fi +dir="$1" + +debug "command: {$command}" +debug "quiet: {$quiet}" +debug "revs: {$revs}" +debug "dir: {$dir}" + +cache_setup() +{ + cachedir="$GIT_DIR/subtree-cache/$dir" + rm -rf "$cachedir" || die "Can't delete old cachedir: $cachedir" + mkdir -p "$cachedir" || die "Can't create new cachedir: $cachedir" + debug "Using cachedir: $cachedir" >&2 + echo "$cachedir" +} + +cache_get() +{ + for oldrev in $*; do + if [ -r "$cachedir/$oldrev" ]; then + read newrev <"$cachedir/$oldrev" + echo $newrev + fi + done +} + +cache_set() +{ + oldrev="$1" + newrev="$2" + if [ -e "$cachedir/$oldrev" ]; then + die "cache for $oldrev already exists!" + fi + echo "$newrev" >"$cachedir/$oldrev" +} + +cmd_split() +{ + debug "Splitting $dir..." + cache_setup || exit $? + + git rev-list --reverse --parents $revs -- "$dir" | + while read rev parents; do + newparents=$(cache_get $parents) + echo "rev: $rev / $newparents" + + git ls-tree $rev -- "$dir" | + while read mode type tree name; do + p="" + for parent in $newparents; do + p="$p -p $parent" + done + newrev=$(echo synthetic | git commit-tree $tree $p) \ + || die "Can't create new commit for $rev / $tree" + cache_set $rev $newrev + done + done + + exit 0 +} + +cmd_merge() +{ + die "merge command not implemented yet" +} + +"cmd_$command" diff --git a/shellopts.sh b/shellopts.sh new file mode 100644 index 000000000..42644cd01 --- /dev/null +++ b/shellopts.sh @@ -0,0 +1 @@ +export PATH=$PWD:$PATH -- 2.30.2