M add => add +3 -3
@@ 16,11 16,11 @@ if(~ $remove 1){
if(~ $#* 0)
exec aux/usage
-paths=`$nl{cleanname -d $gitrel $*}
+paths=`$nl{cleanname -d $gitrel $* | drop $gitroot}
if(~ $add tracked)
- files=`$nl{walk -f $paths}
+ files=`$nl{walk -f ./$paths}
if not
- files=`$nl{cd .git/index9/tracked/ && walk -f $paths}
+ files=`$nl{cd .git/index9/tracked/ && walk -f ./$paths}
for(f in $files){
if(! ~ `$nl{cleanname $f} .git/*){
M branch => branch +2 -2
@@ 32,7 32,7 @@ if not
orig=`{git/query HEAD}
if (~ $#baseref 1)
base=`{git/query $baseref} || exit 'bad base'
-if not if(test -e .git/$new)
+if not if(~ $#newbr 0)
base=`{git/query $new}
if not
base=`{git/query HEAD}
@@ 41,7 41,6 @@ if(~ $#newbr 0){
if(! ~ $#baseref 0)
die update would clobber $branch with $baseref
baseref=`$nl{echo -n $new | sed s@refs/heads/@refs/remotes/origin/@}
- echo $baseref
if(! test -e .git/$new)
if(! base=`{git/query $baseref})
die could not find branch $branch
@@ 119,4 118,5 @@ if(! ~ $#deleted 0){
}
echo ref: $new > .git/HEAD
+echo $new: `{git/query $new}
exit ''
M clone => clone +6 -8
@@ 7,7 7,7 @@ eval `''{aux/getflags $*} || exec aux/usage
if(~ $debug 1)
debug=(-d)
-remote=`{echo $1 | subst -g '/*$'}
+remote=`{echo $1 | sed 's@/*$@@'}
local=$2
if(~ $#remote 0)
@@ 79,19 79,17 @@ fn clone{
tree=.git/fs/HEAD/tree
lbranch=`{git/branch}
- rbranch=`{echo $lbranch | subst '^heads' 'remotes/origin'}
+ rbranch=`{echo $lbranch | subst 'heads' 'remotes/origin'}
echo checking out repository...
if(test -f .git/refs/$rbranch){
cp .git/refs/$rbranch .git/refs/$lbranch
git/fs
@ {builtin cd $tree && tar cif /fd/1 .} | @ {tar xf /fd/0} \
|| die 'checkout failed:' $status
- for(f in `$nl{walk -f $tree | subst '^'$tree'/*'}){
- if(! ~ $#f 0){
- idx=.git/index9/tracked/$f
- mkdir -p `$nl{basename -d $idx}
- walk -eq $f > $idx
- }
+ for(f in `$nl{walk -f $tree | drop $tree}){
+ idx=.git/index9/tracked/$f
+ mkdir -p `$nl{basename -d $idx}
+ walk -eq ./$f > $idx
}
}
if not{
M export => export +1 -1
@@ 42,7 42,7 @@ for(c in $commits){
bind $cp/tree b
echo From: `{cat $cp/author}
- echo Date: `{date -um `{mtime $cp/author | awk '{print $1}'}}
+ echo Date: `{date -uf'WW, DD MMM YYYY hh:mm:ss Z' `{walk -em $cp/author}}
<$cp/msg awk '
NR == 1 {
n = ENVIRON["n"]
M fetch.c => fetch.c +10 -4
@@ 218,16 218,16 @@ fetchpack(Conn *c)
want = earealloc(want, refsz, sizeof(want[0]));
ref = earealloc(ref, refsz, sizeof(ref[0]));
}
- ref[nref] = estrdup(sp[1]);
if(hparse(&want[nref], sp[0]) == -1)
sysfatal("invalid hash %s", sp[0]);
- if (resolveremote(&have[nref], ref[nref]) == -1)
+ if (resolveremote(&have[nref], sp[1]) == -1)
memset(&have[nref], 0, sizeof(have[nref]));
+ ref[nref] = estrdup(sp[1]);
nref++;
}
if(listonly){
flushpkt(c);
- return 0;
+ goto showrefs;
}
if(writephase(c) == -1)
@@ 298,8 298,14 @@ fetchpack(Conn *c)
if(rename(packtmp, idxtmp, h) == -1)
fail(packtmp, idxtmp, "could not rename indexed pack: %r");
- for(i = 0; i < nref; i++)
+showrefs:
+ for(i = 0; i < nref; i++){
print("remote %s %H local %H\n", ref[i], want[i], have[i]);
+ free(ref[i]);
+ }
+ free(ref);
+ free(want);
+ free(have);
return 0;
}
M merge => merge +2 -3
@@ 7,13 7,12 @@ fn merge{
basebr=$gitfs/object/$2/tree
theirbr=$gitfs/object/$3/tree
- all=`$nl{{git/query -c $1 $2; git/query -c $2 $3} | sed 's/^..//' | \
- subst -g '^('$ourbr'|'$basebr'|'$theirbr')/*' | sort | uniq}
+ all=`$nl{{git/query -c $1 $2; git/query -c $2 $3} | sed 's/^..//' | sort | uniq}
for(f in $all){
ours=$ourbr/$f
base=$basebr/$f
theirs=$theirbr/$f
- merge1 $f $theirs $base $ours
+ merge1 ./$f $theirs $base $ours
}
}
M mkfile => mkfile +0 -6
@@ 51,12 51,6 @@ install:V:
mk $MKFLAGS $i.install
for (i in $RC)
mk $MKFLAGS $i.rcinstall
- cp git.1.man /sys/man/1/git
- cp gitfs.4.man /sys/man/4/gitfs
- cp common.rc /sys/lib/git/common.rc
-
-uninstall:V:
- rm -rf $BIN /sys/lib/git /sys/man/1/git /sys/man/4/gitfs
%.rcinstall:V:
cp $stem $BIN/$stem
M pack.c => pack.c +2 -1
@@ 1676,7 1676,8 @@ genpack(int fd, Meta **meta, int nmeta, Hash *h, int odelta)
for(i = 0; i < nmeta; i++){
pct = showprogress((i*100)/nmeta, pct);
m = meta[i];
- if((m->off = Boffset(bfd)) == -1)
+ m->off = Boffset(bfd);
+ if(m->off == -1)
goto error;
if((o = readobject(m->obj->hash)) == nil)
return -1;
M pull => pull +2 -2
@@ 75,8 75,8 @@ if(! ~ `{git/query HEAD $remote @} `{git/query HEAD}){
# The remote is directly ahead of the local, and we have
# no local commits that need merging.
if(~ $#quiet 0)
- git/log -s -e $local'..'$remote >[1=2]
+ git/log -s -e $local'..'$remote
echo
-echo $remote':' `{git/query $local} '=>' `{git/query $remote} >[1=2]
+echo $remote':' `{git/query $local} '=>' `{git/query $remote}
git/branch -mnb $remote $local
exit ''
M ref.c => ref.c +70 -1
@@ 232,6 232,69 @@ lca(Eval *ev)
return 0;
}
+int
+parentof(Eval *ev)
+{
+ Objq *q, *n, *e;
+ Object *p, *c;
+ Objset seen;
+ int i, r;
+
+ print("parentof\n");
+ if(ev->nstk < 2){
+ werrstr("parentof needs 2 objects");
+ return -1;
+ }
+ osinit(&seen);
+ r = 0;
+ p = pop(ev);
+ c = pop(ev);
+ q = emalloc(sizeof(Objq));
+ q->o = ref(p);
+ e = q;
+ if(p->type != GCommit || c->type != GCommit){
+ werrstr("object is not commit");
+ return -1;
+ }
+ while(q != nil){
+ if(oshas(&seen, q->o->hash))
+ goto next;
+ osadd(&seen, q->o);
+ if(hasheq(&q->o->hash, &c->hash)){
+ push(ev, c);
+ goto out;
+ }
+ for(i = 0; i < q->o->commit->nparent; i++){
+ if((c = readobject(q->o->commit->parent[i])) == nil){
+ r = -1;
+ goto out;
+ }
+ if(c->type != GCommit){
+ fprint(2, "warning: %H does not point at commit\n", c->hash);
+ unref(c);
+ continue;
+ }
+ n = emalloc(sizeof(Objq));
+ n->next = nil;
+ n->o = c;
+ e->next = n;
+ e = n;
+ unref(c);
+ }
+next:
+ n = q->next;
+ free(q);
+ q = n;
+ }
+out:
+ osclear(&seen);
+ for(; q != nil; q = n) {
+ n = q->next;
+ free(q);
+ }
+ return r;
+}
+
static int
repaint(Objset *keep, Objset *drop, Object *o)
{
@@ 352,6 415,7 @@ findtwixt(Hash *head, int nhead, Hash *tail, int ntail, Object ***res, int *nres
}
next:
n = q->next;
+ unref(q->o);
free(q);
q = n;
}
@@ 545,13 609,18 @@ evalpostfix(Eval *ev)
while(1){
eatspace(ev);
- switch(ev->p[0]){
+ switch(*ev->p){
case '^':
case '~':
ev->p++;
if(parent(ev) == -1)
return -1;
break;
+ case '<':
+ ev->p++;
+ if(parentof(ev) == -1)
+ return -1;
+ break;
case '@':
ev->p++;
if(lca(ev) == -1)
M revert => revert +2 -2
@@ 11,8 11,8 @@ commit=$gitfs/HEAD
if(~ $#query 1)
commit=`{git/query -p $query}
-files=`$nl{cleanname -d $gitrel $*}
-for(f in `$nl{cd $commit/tree/ && walk -f $files}){
+files=`$nl{cleanname -d $gitrel $* | drop $gitroot}
+for(f in `$nl{cd $commit/tree/ && walk -f ./$files}){
mkdir -p `{basename -d $f}
cp -x -- $commit/tree/$f $f
git/add $f
M save.c => save.c +9 -7
@@ 15,16 15,18 @@ enum {
};
int
-gitmode(int m)
+gitmode(Dirent *e)
{
- if(m & DMDIR) /* directory */
+ if(e->islink)
+ return 0120000;
+ else if(e->ismod)
+ return 0160000;
+ else if(e->mode & DMDIR)
return 0040000;
- else if(m & 0111) /* executable */
+ else if(e->mode & 0111)
return 0100755;
- else if(m != 0) /* regular */
+ else
return 0100644;
- else /* symlink */
- return 0120000;
}
int
@@ 141,7 143,7 @@ writetree(Dirent *ent, int nent, Hash *h)
for(d = ent; d != ent + nent; d++){
if(strlen(d->name) >= 255)
sysfatal("overly long filename: %s", d->name);
- t = seprint(t, etxt, "%o %s", gitmode(d->mode), d->name) + 1;
+ t = seprint(t, etxt, "%o %s", gitmode(d), d->name) + 1;
memcpy(t, d->h.h, sizeof(d->h.h));
t += sizeof(d->h.h);
}