-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit-append-repo
executable file
·52 lines (36 loc) · 1.46 KB
/
git-append-repo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/bash
# in repo R# git-append-repo S foo
# # where S is a repository (remote or local), and foo is a (not yet existing) subdirectory of the current directory,
# # which must be located in the working directory of another repository (let's call that repository R)
# =>
# say R's commit history was R1--R2--R3--R4 and S's was S1--S2--S3, then after the command completes, R will have history R1--R2--R3--R4--S1'--S2'--S3'
# where any Sx' will be identical to Sx except that any path a/b/c in Sx will be foo/a/b/c in Sx'
set -e
git status >/dev/null # make sure we're in a git repo
repo="$1"
subdir="$2"
repobranch="${3:-master}"
if [ -z "$repo" -o -z "$subdir" -o -e "$subdir" ]; then
echo "usage: $0 <git repo> <subdir to be created>" >&2
exit 1
fi
git fetch -q $repo $repobranch
git rev-list --reverse FETCH_HEAD | while read commit; do
echo "processing commit $commit" >&2
rm -rf "$subdir"
mkdir -p "$subdir"
git ls-tree -r -z --full-name --full-tree $commit | while read -d $'\0' line; do
read mode type id path <<<"$line"
if [ "$type" != "blob" ]; then
echo "non-blob ($type) object $id in commit $commit" >&2
continue
fi
echo "file: blob=$id mode=$mode path=$path" >&2
pathdir=$(dirname "$path")
mkdir -p "$subdir/$pathdir"
git show "$id" >"$subdir/$path"
chmod "${mode#??}" "$subdir/$path"
done
git add -A "$subdir"
git commit -C "$commit"
done