~ori/git9

52bd6a558338111c5f787ccc1d3b5f999c0e010f — Ori Bernstein 3 years ago 367ff60
all: sync with 9front fixes.
11 files changed, 125 insertions(+), 82 deletions(-)

M add -rwxr-xr-x => -rw-r--r--
M branch
M clone
M commit -rwxr-xr-x => -rw-r--r--
M common.rc
M diff -rwxr-xr-x => -rw-r--r--
M init
M mkfile
M proto.c
M save.c
M serve.c
M add => add +6 -5
@@ 16,17 16,18 @@ if(~ $remove 1){
if(~ $#* 0)
	exec aux/usage

paths=`$nl{cleanname -d $gitrel $*}
if(~ $add tracked)
	files=`$nl{walk -f $gitrel/$*}
	files=`$nl{walk -f $paths}
if not
	files=`$nl{cd .git/index9/tracked/ && walk -f $gitrel/$*}
	files=`$nl{cd .git/index9/tracked/ && walk -f $paths}

for(f in $files){
	if(! ~ `{cleanname $f} .git/*){
	if(! ~ `$nl{cleanname $f} .git/*){
		addpath=.git/index9/$add/$f
		delpath=.git/index9/$del/$f
		mkdir -p `{basename -d $addpath}
		mkdir -p `{basename -d $delpath}
		mkdir -p `$nl{basename -d $addpath}
		mkdir -p `$nl{basename -d $delpath}
		# We don't want a matching qid, so that
		# git/walk doesn't think this came from
		# a checkout.

M branch => branch +5 -3
@@ 60,9 60,10 @@ if(~ $#newbr 0){
commit=`{git/query $base} || die 'branch does not exist:' $base
if(~ $new */*)
	mkdir -p .git/`{basename -d $new}
echo $commit > .git/$new
if(! ~ $#stay 0)
if(! ~ $#stay 0){
	echo $commit > .git/$new
	exit
}
basedir=`{git/query -p $base}
dirtypaths=()
cleanpaths=($modified $deleted)


@@ 74,11 75,12 @@ if(! ~ $#dirtypaths 0){
	cleanpaths=`$nl{echo $"x$nl$"y | sort | uniq -u}
}
if(! ~ $#cleanpaths 0)
	cleandirs=`$nl{{for(p in $cleanpaths) basename -d $p} | uniq}
	cleandirs=`$nl{echo $nl^$cleanpaths | sed 's@/[^/]+/?$@@' | uniq}
if(! ~ $#cleandirs 0){
	mkdir -p $cleandirs
	mkdir -p .git/index9/tracked/$cleandirs
}
echo $commit > .git/$new
for(m in $cleanpaths){
	# Modifications can turn a file into
	# a directory, or vice versa, so we

M clone => clone +1 -1
@@ 17,7 17,7 @@ if(~ $#local 0)
if(~ $#branch 1)
	branchflag=(-b $branch)

if(! ~ `{ls $local | wc -l} 0)
if(test -e $local)
	die 'repository already exists:' $local

fn clone{

M commit => commit +1 -1
@@ 135,7 135,7 @@ if not if(~ $#revise 1){

files=()
if(! ~ $#* 0)
	files=`$nl{git/walk -c `$nl{cleanname $gitrel/$*}}
	files=`$nl{git/walk -c `$nl{cleanname -d $gitrel $*}}
if(~ $status '' || ~ $#files 0 && ! test -f .git/index9/merge-parents && ~ $#revise 0)
	die 'nothing to commit' $status
@{

M common.rc => common.rc +6 -5
@@ 40,12 40,13 @@ fn present {
}

# merge1 out theirs base ours
fn merge1 {
fn merge1 {@{
	rfork e
	n=$pid
	out=$1
	theirs=$2
	ours=$2
	base=$3
	ours=$4
	theirs=$4
	tmp=$out.tmp
	while(test -f $tmp){
		tmp=$tmp.$n


@@ 59,7 60,7 @@ fn merge1 {
	if(! test -f $theirs)
		theirs=/dev/null
	if(! ape/diff3 -3 -m $ours $base $theirs > $tmp)
		echo merge needed: $out
		echo merge needed: $out >[1=2]

	if(present $ours $base $theirs){
		mv $tmp $out


@@ 69,7 70,7 @@ fn merge1 {
		rm -f $tmp $out
		git/rm $out
	}
}
}}

fn gitup{
	gitroot=`{git/conf -r >[2]/dev/null}

M diff => diff +1 -1
@@ 12,7 12,7 @@ if(~ $#commit 0)

files=()
if(! ~ $#* 0)
	files=`{cleanname $gitrel/$*}
	files=`{cleanname -d $gitrel $*}

branch=`{git/query -p $commit}
if(~ $summarize 1){

M init => init +1 -1
@@ 20,7 20,7 @@ if(~ $#upstream 0){
}

mkdir -p $dir/.git/refs/^(heads remotes)
mkdri -p $dir/.git/fs
mkdir -p $dir/.git/fs
>$dir/.git/config {
	echo '[core]'
	echo '	repositoryformatversion = p9.0'

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 proto.c => proto.c +81 -39
@@ 285,11 285,29 @@ dialssh(Conn *c, char *host, char *, char *path, char *direction)
		snprint(cmd, sizeof(cmd), "git-%s-pack", direction);
		dprint(1, "exec ssh '%s' '%s' %s\n", host, cmd, path);
		execl("/bin/ssh", "ssh", host, cmd, path, nil);
	}else{
		close(pfd[0]);
		c->type = ConnSsh;
		c->rfd = pfd[1];
		c->wfd = dup(pfd[1], -1);
		sysfatal("exec: %r");
	}
	close(pfd[0]);
	c->type = ConnSsh;
	c->rfd = pfd[1];
	c->wfd = dup(pfd[1], -1);
	return 0;
}

static int
githandshake(Conn *c, char *host, char *path, char *direction)
{
	char *p, *e, cmd[512];

	p = cmd;
	e = cmd + sizeof(cmd);
	p = seprint(p, e - 1, "git-%s-pack %s", direction, path);
	if(host != nil)
		p = seprint(p + 1, e, "host=%s", host);
	if(writepkt(c, cmd, p - cmd + 1) == -1){
		fprint(2, "failed to write message\n");
		closeconn(c);
		return -1;
	}
	return 0;
}


@@ 297,7 315,7 @@ dialssh(Conn *c, char *host, char *, char *path, char *direction)
static int
dialhjgit(Conn *c, char *host, char *port, char *path, char *direction, int auth)
{
	char *ds, *p, *e, cmd[512];
	char *ds;
	int pid, pfd[2];

	if((ds = netmkaddr(host, "tcp", port)) == nil)


@@ 317,30 335,26 @@ dialhjgit(Conn *c, char *host, char *port, char *path, char *direction, int auth
		else
			execl("/bin/tlsclient", "tlsclient", ds, nil);
		sysfatal("exec: %r");
	}else{
		close(pfd[0]);
		p = cmd;
		e = cmd + sizeof(cmd);
		p = seprint(p, e - 1, "git-%s-pack %s", direction, path);
		p = seprint(p + 1, e, "host=%s", host);
		c->type = ConnGit9;
		c->rfd = pfd[1];
		c->wfd = dup(pfd[1], -1);
		if(writepkt(c, cmd, p - cmd + 1) == -1){
			fprint(2, "failed to write message\n");
			close(c->rfd);
			close(c->wfd);
			return -1;
		}
	}
	return 0;
	close(pfd[0]);
	c->type = ConnGit9;
	c->rfd = pfd[1];
	c->wfd = dup(pfd[1], -1);
	return githandshake(c, host, path, direction);
}

void
initconn(Conn *c, int rd, int wr)
{
	c->type = ConnGit;
	c->rfd = rd;
	c->wfd = wr;
}

static int
dialgit(Conn *c, char *host, char *port, char *path, char *direction)
{
	char *ds, *p, *e, cmd[512];
	char *ds;
	int fd;

	if((ds = netmkaddr(host, "tcp", port)) == nil)


@@ 349,27 363,51 @@ dialgit(Conn *c, char *host, char *port, char *path, char *direction)
	fd = dial(ds, nil, nil, nil);
	if(fd == -1)
		return -1;
	p = cmd;
	e = cmd + sizeof(cmd);
	p = seprint(p, e - 1, "git-%s-pack %s", direction, path);
	p = seprint(p + 1, e, "host=%s", host);
	c->type = ConnGit;
	c->rfd = fd;
	c->wfd = dup(fd, -1);
	if(writepkt(c, cmd, p - cmd + 1) == -1){
		fprint(2, "failed to write message\n");
		close(fd);
		return -1;
	}
	return 0;
	return githandshake(c, host, path, direction);
}

void
initconn(Conn *c, int rd, int wr)
static int
servelocal(Conn *c, char *path, char *direction)
{
	int pid, pfd[2];

	if(pipe(pfd) == -1)
		sysfatal("unable to open pipe: %r");
	pid = fork();
	if(pid == -1)
		sysfatal("unable to fork");
	if(pid == 0){
		close(pfd[1]);
		dup(pfd[0], 0);
		dup(pfd[0], 1);
		execl("/bin/git/serve", "serve", "-w", nil);
		sysfatal("exec: %r");
	}
	close(pfd[0]);
	c->type = ConnGit;
	c->rfd = rd;
	c->wfd = wr;
	c->rfd = pfd[1];
	c->wfd = dup(pfd[1], -1);
	return githandshake(c, nil, path, direction);
}

static int
localrepo(char *uri, char *path, int npath)
{
	int fd;

	snprint(path, npath, "%s/.git/../", uri);
	fd = open(path, OREAD);
	if(fd < 0)
		return -1;
	if(fd2path(fd, path, npath) != 0){
		close(fd);
		return -1;
	}
	close(fd);
	return 0;
}

int


@@ 378,12 416,16 @@ gitconnect(Conn *c, char *uri, char *direction)
	char proto[Nproto], host[Nhost], port[Nport];
	char repo[Nrepo], path[Npath];

	memset(c, 0, sizeof(Conn));
	c->rfd = c->wfd = c->cfd = -1;

	if(localrepo(uri, path, sizeof(path)) == 0)
		return servelocal(c, path, direction);

	if(parseuri(uri, proto, host, port, path, repo) == -1){
		werrstr("bad uri %s", uri);
		return -1;
	}

	memset(c, 0, sizeof(Conn));
	if(strcmp(proto, "ssh") == 0)
		return dialssh(c, host, port, path, direction);
	else if(strcmp(proto, "git") == 0)

M save.c => save.c +16 -7
@@ 345,18 345,25 @@ void
main(int argc, char **argv)
{
	Hash th, ch, parents[Maxparents];
	char *msg, *name, *email, *dstr;
	int i, r, nparents;
	char *msg, *name, *email, *dstr, cwd[1024];
	int i, r, ncwd, nparents;
	vlong date;
	Object *t;

	gitinit();
	gitinit();
	if(access(".git", AEXIST) != 0)
		sysfatal("could not find git repo: %r");
	if(getwd(cwd, sizeof(cwd)) == nil)
		sysfatal("getcwd: %r");
	msg = nil;
	name = nil;
	email = nil;
	dstr = nil;
	date = time(nil);
	nparents = 0;
	gitinit();
	ncwd = strlen(cwd);

	ARGBEGIN{
	case 'm':	msg = EARGF(usage());	break;
	case 'n':	name = EARGF(usage());	break;


@@ 385,12 392,14 @@ main(int argc, char **argv)
	}
	if(msg == nil || name == nil)
		usage();
	for(i = 0; i < argc; i++)
	for(i = 0; i < argc; i++){
		cleanname(argv[i]);
		if(*argv[i] == '/' && strncmp(argv[i], cwd, ncwd) == 0)
			argv[i] += ncwd;
		while(*argv[i] == '/')
			argv[i]++;
	}

	gitinit();
	if(access(".git", AEXIST) != 0)
		sysfatal("could not find git repo: %r");
	t = findroot();
	r = treeify(t, argv, argv + argc, 0, &th);
	if(r == -1)

M serve.c => serve.c +7 -13
@@ 5,8 5,7 @@

#include "git.h"

char	*pathpfx = "/usr/git";
char	*namespace = nil;
char	*pathpfx = nil;
int	allowwrite;

int


@@ 498,7 497,6 @@ void
main(int argc, char **argv)
{
	char *repo, cmd[32], buf[512];
	char *user;
	Conn c;

	ARGBEGIN{


@@ 510,9 508,6 @@ main(int argc, char **argv)
		if(*pathpfx != '/')
			sysfatal("path prefix must begin with '/'");
		break;
	case 'n':
		namespace=EARGF(usage());
		break;
	case 'w':
		allowwrite++;
		break;


@@ 522,14 517,13 @@ main(int argc, char **argv)
	}ARGEND;

	gitinit();
	user = "none";
	interactive = 0;
	if(allowwrite)
		user = getuser();
	if(newns(user, namespace) == -1)
		sysfatal("addns: %r");
	if(bind(pathpfx, "/", MREPL) == -1)
		sysfatal("bind: %r");
	if(rfork(RFNAMEG) == -1)
		sysfatal("rfork: %r");
	if(pathpfx != nil){
		if(bind(pathpfx, "/", MREPL) == -1)
			sysfatal("bind: %r");
	}
	if(rfork(RFNOMNT) == -1)
		sysfatal("rfork: %r");