~ori/git9

1b4c50bd8f0b80875c50948e30b9b6501c71f412 — Ori Bernstein 3 years ago 0337805
git: sync with 9front git
12 files changed, 109 insertions(+), 40 deletions(-)

M add
M branch
M clone
M export
M fetch.c
M merge
M mkfile
M pack.c
M pull
M ref.c
M revert
M save.c
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);
	}