]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/git/clone
git: better handling of absolute paths, regex metachars
[plan9front.git] / sys / src / cmd / git / clone
1 #!/bin/rc
2 rfork en
3 . /sys/lib/git/common.rc
4
5 flagfmt='d:debug, b:branch branch'; args='remote [local]'
6 eval `''{aux/getflags $*} || exec aux/usage
7 if(~ $debug 1)
8         debug=(-d)
9
10 remote=`{echo $1 | sed  's@/*$@@'}
11 local=$2
12
13 if(~ $#remote 0)
14         exec aux/usage
15 if(~ $#local 0)
16         local=`{basename $remote .git}
17 if(~ $#branch 1)
18         branchflag=(-b $branch)
19
20 if(test -e $local)
21         die 'repository already exists:' $local
22
23 fn clone{
24         flag +e
25         mkdir -p $local/.git
26         mkdir -p $local/.git/fs
27         mkdir -p $local/.git/objects/pack/
28         mkdir -p $local/.git/refs/heads/
29         
30         cd $local
31         
32         >>.git/config {
33                 echo '[remote "origin"]'
34                 echo '  url='$remote
35         }
36         {git/fetch  $debug $branchflag $remote >[2=3] | awk '
37                 BEGIN{
38                         headref=""
39                         if(ENVIRON["branch"] != "")
40                                 headref="refs/remotes/origin/"ENVIRON["branch"]
41                         headhash=""
42                 }
43                 /^symref / && headref == "" {
44                         if($2 == "HEAD"){
45                                 gsub("^refs/heads", "refs/remotes/origin", $3)
46                                 gsub("^refs/tags", "refs/remotes/origin/tags", $3)
47                         }
48                 }
49                 /^remote /{
50                         if($2=="HEAD"){
51                                 headhash=$3
52                         }else if(match($2, "^refs/(heads|tags)/")){
53                                 gsub("^refs/heads", "refs/remotes/origin", $2)
54                                 if($2 == headref || (headref == "" && $3 == headhash))
55                                         headref=$2
56                                 outfile = ".git/" $2
57                                 outdir = outfile
58                                 gsub("/?[^/]*/?$", "", outdir)
59                                 system("mkdir -p "outdir)
60                                 print $3 > outfile
61                                 close(outfile)
62                         }
63                 }
64                 END{
65                         if(headref != ""){
66                                 remote = headref;
67                                 refdir = headref;
68                                 gsub("/?[^/]*/?$", "", refdir)
69                                 gsub("^refs/remotes/origin", "refs/heads", headref)
70                                 system("mkdir -p .git/"refdir);
71                                 system("cp .git/" remote " .git/" headref)
72                                 print "ref: " headref > ".git/HEAD"
73                         }else if(headhash != ""){
74                                 print "warning: detached head "headhash > "/fd/2"
75                                 print headhash > ".git/HEAD"
76                         }
77                 }
78         '} |[3] tr '\x0d' '\x0a' || die 'could not clone repository'
79
80         tree=.git/fs/HEAD/tree
81         lbranch=`{git/branch}
82         rbranch=`{echo $lbranch | subst 'heads' 'remotes/origin'}
83         echo checking out repository...
84         if(test -f .git/refs/$rbranch){
85                 cp .git/refs/$rbranch .git/refs/$lbranch
86                 git/fs
87                 @ {builtin cd $tree && tar cif /fd/1 .} | @ {tar xf /fd/0} \
88                         || die 'checkout failed:' $status
89                 for(f in `$nl{walk -f $tree | drop $tree}){
90                         idx=.git/index9/tracked/$f
91                         mkdir -p `$nl{basename -d $idx}
92                         walk -eq ./$f > $idx
93                 }
94         }
95         if not{
96                 echo no default branch >[1=2]
97                 echo check out your code with git/branch >[1=2]
98         }
99 }
100
101 fn sigint {
102         echo cancelled clone $remote: cleaning $local >[1=2]
103         rm -rf $local
104         exit interrupted
105 }
106
107 @{clone}
108 st=$status
109 if(! ~ $st ''){
110         echo failed to clone $remote: cleaning $local >[1=2]
111         rm -rf $local
112         exit $st
113 }
114 exit ''