basic options parsing and whatnot.
Avery Pennarun committed
Apr 24, 2009 at 14:13 UTC
0ca71b3737cbb26fbf037aa15b3f58735785e6e3
4 files changed
+126
.gitignore
new
+1
@@ -0,0 +1 @@
1
+*~
git-subtree
new
+1
@@ -0,0 +1 @@
1
+git-subtree.sh
\ No newline at end of file
git-subtree.sh
new
+123
@@ -0,0 +1,123 @@
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
+#
7
+OPTS_SPEC="\
8
+git subtree split <revisions> -- <subdir>
9
+git subtree merge
10
+
11
+git subtree does foo and bar!
12
+--
13
+h,help show the help
14
+q quiet
15
+v verbose
16
+"
17
+eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
18
+. git-sh-setup
19
+require_work_tree
20
+
21
+quiet=
22
+command=
23
+
24
+debug()
25
+{
26
+ if [ -z "$quiet" ]; then
27
+ echo "$@" >&2
28
+ fi
29
+}
30
+
31
+#echo "Options: $*"
32
+
33
+while [ $# -gt 0 ]; do
34
+ opt="$1"
35
+ shift
36
+ case "$opt" in
37
+ -q) quiet=1 ;;
38
+ --) break ;;
39
+ esac
40
+done
41
+
42
+command="$1"
43
+shift
44
+case "$command" in
45
+ split|merge) ;;
46
+ *) die "Unknown command '$command'" ;;
47
+esac
48
+
49
+revs=$(git rev-parse --default HEAD --revs-only "$@") || exit $?
50
+dirs="$(git rev-parse --sq --no-revs --no-flags "$@")" || exit $?
51
+
52
+#echo "dirs is {$dirs}"
53
+eval $(echo set -- $dirs)
54
+if [ "$#" -ne 1 ]; then
55
+ die "Must provide exactly one subtree dir (got $#)"
56
+fi
57
+dir="$1"
58
+
59
+debug "command: {$command}"
60
+debug "quiet: {$quiet}"
61
+debug "revs: {$revs}"
62
+debug "dir: {$dir}"
63
+
64
+cache_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
+
73
+cache_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
+
83
+cache_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
+
93
+cmd_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
+
118
+cmd_merge()
119
+{
120
+ die "merge command not implemented yet"
121
+}
122
+
123
+"cmd_$command"
shellopts.sh
new
+1
@@ -0,0 +1 @@
1
+export PATH=$PWD:$PATH