git-subtree.shon commit basic options parsing and whatnot. (0ca71b3)
   1#!/bin/bash
   2#
   3# git-subtree.sh: split/join git repositories in subdirectories of this one
   4#
   5# Copyright (c) 2009 Avery Pennarun <apenwarr@gmail.com>
   6#
   7OPTS_SPEC="\
   8git subtree split <revisions> -- <subdir>
   9git subtree merge 
  10
  11git subtree does foo and bar!
  12--
  13h,help   show the help
  14q        quiet
  15v        verbose
  16"
  17eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
  18. git-sh-setup
  19require_work_tree
  20
  21quiet=
  22command=
  23
  24debug()
  25{
  26        if [ -z "$quiet" ]; then
  27                echo "$@" >&2
  28        fi
  29}
  30
  31#echo "Options: $*"
  32
  33while [ $# -gt 0 ]; do
  34        opt="$1"
  35        shift
  36        case "$opt" in
  37                -q) quiet=1 ;;
  38                --) break ;;
  39        esac
  40done
  41
  42command="$1"
  43shift
  44case "$command" in
  45        split|merge) ;;
  46        *) die "Unknown command '$command'" ;;
  47esac
  48
  49revs=$(git rev-parse --default HEAD --revs-only "$@") || exit $?
  50dirs="$(git rev-parse --sq --no-revs --no-flags "$@")" || exit $?
  51
  52#echo "dirs is {$dirs}"
  53eval $(echo set -- $dirs)
  54if [ "$#" -ne 1 ]; then
  55        die "Must provide exactly one subtree dir (got $#)"
  56fi
  57dir="$1"
  58
  59debug "command: {$command}"
  60debug "quiet: {$quiet}"
  61debug "revs: {$revs}"
  62debug "dir: {$dir}"
  63
  64cache_setup()
  65{
  66        cachedir="$GIT_DIR/subtree-cache/$dir"
  67        rm -rf "$cachedir" || die "Can't delete old cachedir: $cachedir"
  68        mkdir -p "$cachedir" || die "Can't create new cachedir: $cachedir"
  69        debug "Using cachedir: $cachedir" >&2
  70        echo "$cachedir"
  71}
  72
  73cache_get()
  74{
  75        for oldrev in $*; do
  76                if [ -r "$cachedir/$oldrev" ]; then
  77                        read newrev <"$cachedir/$oldrev"
  78                        echo $newrev
  79                fi
  80        done
  81}
  82
  83cache_set()
  84{
  85        oldrev="$1"
  86        newrev="$2"
  87        if [ -e "$cachedir/$oldrev" ]; then
  88                die "cache for $oldrev already exists!"
  89        fi
  90        echo "$newrev" >"$cachedir/$oldrev"
  91}
  92
  93cmd_split()
  94{
  95        debug "Splitting $dir..."
  96        cache_setup || exit $?
  97        
  98        git rev-list --reverse --parents $revs -- "$dir" |
  99        while read rev parents; do
 100                newparents=$(cache_get $parents)
 101                echo "rev: $rev / $newparents"
 102                
 103                git ls-tree $rev -- "$dir" |
 104                while read mode type tree name; do
 105                        p=""
 106                        for parent in $newparents; do
 107                                p="$p -p $parent"
 108                        done
 109                        newrev=$(echo synthetic | git commit-tree $tree $p) \
 110                                || die "Can't create new commit for $rev / $tree"
 111                        cache_set $rev $newrev
 112                done
 113        done
 114        
 115        exit 0
 116}
 117
 118cmd_merge()
 119{
 120        die "merge command not implemented yet"
 121}
 122
 123"cmd_$command"