Test commit
[cogito/jonas.git] / cg-clone
blob0a5205492c33bc453d8f3ad0758b1d72543e9159
1 #!/usr/bin/env bash
3 # Clone a remote repository
4 # Copyright (c) Petr Baudis, 2005
6 # This clones a remote GIT repository and checks it out locally.
8 # Takes a parameter specifying the location of the source repository and an
9 # optional second parameter specifying the destination. If the second
10 # parameter is omitted, the basename of the source repository is used as the
11 # destination.
13 # For detailed description of the location of the source repository format
14 # (available protocols, specifying different remote branch, etc) please see
15 # the `cg-branch-add` documentation.
17 # OPTIONS
18 # -------
19 # -b:: Create a bare repository - do not check out working copy
20 # Create only the bare repository, without a working copy attached;
21 # this is useful e.g. for public repository mirrors. `cg-clone`
22 # is to `cg-init` as `cg-clone -b` is to `cg-admin-setuprepo`.
23 # (Still, if you are setting up a public or a central repository
24 # other people will push into, it might be more practical to just
25 # `cg-admin-setuprepo` it and then populate it with `cg-push`
26 # from the other side.)
28 # -l:: "Borrow" the object database when cloning locally
29 # Instead of hardlinking all the objects, set up an "alternate"
30 # record pointing at the source object database; this will cause
31 # any objects not found locally to be looked up remotely, which
32 # effectively eliminates the need to copy/hardlink the objects
33 # around. This is suitable for very fast cloning of arbitrarily
34 # big repositories, but your repository will become largely useless
35 # if the source repository disappears or gets damaged (note that
36 # it is generally BAD IDEA to prune the original repository if any
37 # repository is borrowing objects from it). The choice is yours.
39 # --reference PATH:: "Borrow" the object database from a third-party source
40 # This does the same thing as '-l' but instead of borrowing the
41 # objects from the source repository, it borrows them from yet
42 # another local repository. E.g. if you have Linus' kernel repository
43 # cloned locally and now want to clone akpm's repository, you can
44 # do something like
46 # ---------------------------------------------------------------
47 # $ cg-clone --reference /path/to/linus/repo \
48 # git://kernel.org/akpm/repo
49 # ---------------------------------------------------------------
51 # and it will download and keep only the objects that are really
52 # missing. Same considerations and warnings on the third-party source
53 # as in the case of '-l' apply. Also, you can reference only local
54 # repositories.
56 # -s:: Clone into the current directory
57 # Clone in the current directory instead of creating a new one.
58 # Specifying both -s and a destination directory makes no sense.
60 # NOTES
61 # -----
62 # If the clone has been interrupted for any reason, do not panic, calmly
63 # cd to the destination directory and run `cg-fetch`, which will in this case
64 # restart the initial clone. Chances are that you will not actually download
65 # any duplicate data. (At the time of writing this, the chances aren't for
66 # the native git protocol and ssh, but this may change in the future).
68 # EXAMPLE USAGE
69 # -------------
70 # If you want to clone the Cogito repository, you can say:
72 # ---------------------------------------------------------------
73 # $ cg-clone http://www.kernel.org/pub/scm/cogito/cogito.git
74 # ---------------------------------------------------------------
76 # and it will be cloned to the 'cogito' subdirectory of the current directory.
78 # To clone the 'next' branch of the Git repository, do e.g.:
80 # ---------------------------------------------------------------
81 # $ cg-clone git://git.kernel.org/pub/scm/git/git.git#next
82 # ---------------------------------------------------------------
84 # Testsuite: Checked as part of t-9105-fetch-local but tests for some features
85 # are missing.
87 USAGE="cg-clone [-l] [-b] [-s] LOCATION [DESTDIR]"
88 _git_repo_unneeded=1
90 . "${COGITO_LIB}"cg-Xlib || exit 1
92 same_dir=
93 repoonly=
94 alternate=
95 reference=()
96 while optparse; do
97 if optparse -l; then
98 alternate=1
99 elif optparse -b; then
100 repoonly=1
101 elif optparse --reference=; then
102 reference[${#reference[@]}]="$OPTARG"
103 elif optparse -s; then
104 same_dir=1
105 else
106 optfail
108 done
110 location="${ARGS[0]}"
112 [ -n "$location" ] || usage
113 location="${location%/}"
115 destdir="${ARGS[1]}"
116 if [ "$destdir" ]; then
117 [ ! "$same_dir" ] || die "specifying both -s and DESTDIR makes no sense"
118 dir="$destdir"
119 else
120 dir="${location%#*}"; dir="${dir%/.git}"; dir="${dir##*/}"; dir="${dir%.git}"
121 [ "$repoonly" ] && dir="$dir.git"
124 if ! echo "$location" | grep -q ":" ; then
125 location=$(echo "$location" | sed -e "s#^[^/]#$(pwd)\/&#")
126 else
127 [ ! "$alternate" ] || die "specifying -l for non-local clone makes no sense"
128 location="$location"
131 if [ ! "$same_dir" ]; then
132 [ -e "$dir" ] && die "$dir/ already exists"
133 if [ "$repoonly" ]; then
134 cg-admin-setuprepo "$dir" || exit $?
135 else
136 mkdir -p "$dir" || exit $?
138 cd "$dir" || exit $?
139 else
140 dir=.
143 if [ "$repoonly" ]; then
144 _git=.
145 export GIT_DIR=.
146 _git_no_wc=1
150 cleanup ()
152 if [ -s "$_git/info/cg-fetch-earlydie" ] && [ ! "$same_dir" ]; then
153 cd ..
154 rm -rf "$dir"
158 cleanup_trap "cleanup"
161 if [ ! "$repoonly" ]; then
162 cg-init -I || die "init failed"
164 echo $$ >"$_git/info/cg-fetch-earlydie"
166 repoloc="$location"
167 [ ! -d "$repoloc/.git/objects" ] || repoloc="$repoloc/.git"
168 [ "$alternate" ] && echo "$repoloc/objects" >> "$_git/objects/info/alternates"
169 for ref in "${reference[@]}"; do
170 relpath=
171 [ "${ref#/}" != "$ref" ] || relpath=1
172 # Relative path; reference is relative to the object repository; we
173 # need to add one .. for objects, another .. for .git/, another .. for
174 # projdir unless ! same_Dir
176 if [ ! "$same_dir" ] && [ "$relpath" ]; then
177 # Relative path, account for project subdir
178 ref="../$ref"
181 [ -d "$ref" ] || die "referenced repository $ref not found"
182 [ ! -d "$ref/.git/objects" ] || ref="$ref/.git"
183 [ -d "$ref/objects" ] || die "reference $ref not a git repository"
184 [ ! "$relpath" ] || ref="../../$ref"
185 echo "$ref/objects" >>"$_git/objects/info/alternates"
186 done
188 cg-branch-add origin "$location"
190 mkdir -p "$_git/info"
191 [ "$repoonly" ] && echo $$ >"$_git/info/cg-fetch-initial-wcless"
192 echo $$ >"$_git/info/cg-fetch-initial"
193 cat >___ <<__EOT__
194 This is a clone-in-progress GIT working tree containing a GIT repository
195 in the .git subdirectory. If you see this file and noone is fetching or
196 cloning in this repository, the clone has been interrupted; you can restart
197 it by issuing this command (it's enough as-is):
199 cg-fetch
200 __EOT__
201 cg-fetch origin || { cleanup; exit 1; }
203 echo "Cloned to $dir/ (origin $location available as branch \"origin\")"