git-cache
3.56 KB
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/bin/sh
git_cache() {
git -C "${GIT_CACHE_DIR}" $*
}
init() {
set -ex
local _git_dir="$(git_cache rev-parse --git-dir 2>/dev/null)"
test "$_git_dir" == "." -o "$_git_dir" == ".git" || {
mkdir -p "${GIT_CACHE_DIR}"
git_cache init --bare
git_cache config core.compression 1
}
set +ex
}
add() {
set -ex
if [ $# -eq 1 ]; then
local repo="$1"
local name="$(_remote_name $repo)"
else
local repo="$1"
local name="$2"
fi
if ! is_cached "$repo"; then
git_cache remote add "$name" "$repo"
else
echo "git-cache: $url already in cache"
fi
set +ex
}
update() {
set -ex
local REMOTE=${1:---all}
git_cache fetch $REMOTE
set +ex
}
is_cached() {
set +ex
local url="$1"
local REMOTES="$(git_cache remote show)"
for remote in $REMOTES; do
test "$(git_cache remote get-url $remote)" == "$url" && return 0
done
set -ex
return 1
}
list() {
local REMOTES="$(git_cache remote show)"
for remote in $REMOTES; do
echo "${remote}: $(git_cache remote get-url $remote)"
done
}
drop() {
set -ex
local REMOTE=${1}
[ -z "$REMOTE" ] && {
echo "usage: git cache drop <name>"
exit 1
}
git_cache remote remove $REMOTE
set +ex
}
_check_commit() {
git_cache cat-file -e ${1}^{commit}
}
_remote_name() {
basename "$*" .git
}
clone() {
set -ex
local REMOTE="${1}"
local SHA1="${2}"
local REMOTE_NAME="$(_remote_name $REMOTE)"
local TARGET_PATH="${3:-${REMOTE_NAME}}"
if [ "$GIT_CACHE_AUTOADD" == "1" ]; then
if ! is_cached "$REMOTE"; then
add "$REMOTE"
update "$(_remote_name $REMOTE)"
fi
fi
if _check_commit $2 2>&1; then
git init "${TARGET_PATH}"
git_cache tag commit$SHA1 $SHA1 || true # ignore possibly already existing tag
git -C "${TARGET_PATH}" fetch --tags --depth=1 "${GIT_CACHE_DIR}" refs/tags/commit$SHA1
git -C "${TARGET_PATH}" checkout FETCH_HEAD
else
git clone "${REMOTE}" "${TARGET_PATH}"
git -C "${TARGET_PATH}" checkout $SHA1
fi
set +ex
}
usage() {
echo "git cache uses a bare git repository containing all objects from multiple"
echo "upstream git repositories."
echo ""
echo "usage:"
echo ""
echo " git cache init initialize git cache"
echo " git cache add <url> [<name>] add repository <url> with name <name>"
echo " (if no name given, use \"basename $url .git\""
echo " git cache list list cached repositories"
echo " git cache drop <name> drop repo from cache"
echo " git cache update [<name>] fetch repo named <name> (or all)"
echo " git cache clone <url> <SHA1> clone repository <url> from cache"
echo " git cache show-path print's the path that can be used as "
echo " '--reference' parameter"
echo ""
echo "To retrieve objects from cache (will use remote repository if needed):"
echo ' git clone --reference $(git cache show-path) <repo>'
}
ACTION=$1
shift
export GIT_CACHE_DIR=${GIT_CACHE_DIR:-${HOME}/.gitcache}
case $ACTION in
init)
init $*
;;
add)
add $*
;;
update)
update $*
;;
list)
list $*
;;
drop)
drop $*
;;
show-path)
echo ${GIT_CACHE_DIR}
;;
clone)
clone $*
;;
*)
usage
;;
esac