ref: 52bd6a558338111c5f787ccc1d3b5f999c0e010f
parent: 367ff60a52a2d73059476ec80ac2807cf5085162
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jun 5 22:29:56 EDT 2021
all: sync with 9front fixes.
--- a/add
+++ b/add
@@ -16,17 +16,18 @@
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.
--- a/branch
+++ b/branch
@@ -60,9 +60,10 @@
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 @@
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
--- a/clone
+++ b/clone
@@ -17,7 +17,7 @@
if(~ $#branch 1)
branchflag=(-b $branch)
-if(! ~ `{ls $local | wc -l} 0)
+if(test -e $local)
die 'repository already exists:' $local
fn clone{
--- a/commit
+++ b/commit
@@ -135,7 +135,7 @@
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
@{
--- a/common.rc
+++ b/common.rc
@@ -40,12 +40,13 @@
}
# 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 @@
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 @@
rm -f $tmp $out
git/rm $out
}
-}
+}}
fn gitup{
gitroot=`{git/conf -r >[2]/dev/null}
--- a/diff
+++ b/diff
@@ -12,7 +12,7 @@
files=()
if(! ~ $#* 0)
- files=`{cleanname $gitrel/$*}
+ files=`{cleanname -d $gitrel $*}
branch=`{git/query -p $commit}
if(~ $summarize 1){
--- a/init
+++ b/init
@@ -20,7 +20,7 @@
}
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'
--- a/mkfile
+++ b/mkfile
@@ -51,12 +51,6 @@
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
--- a/proto.c
+++ b/proto.c
@@ -285,19 +285,37 @@
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;
+}
+
+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 @@
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,29 +363,53 @@
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
gitconnect(Conn *c, char *uri, char *direction)
{
@@ -378,12 +416,16 @@
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)
--- a/save.c
+++ b/save.c
@@ -345,11 +345,17 @@
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;
@@ -356,7 +362,8 @@
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 @@
}
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)
--- a/serve.c
+++ b/serve.c
@@ -5,8 +5,7 @@
#include "git.h"
-char *pathpfx = "/usr/git";
-char *namespace = nil;
+char *pathpfx = nil;
int allowwrite;
int
@@ -498,7 +497,6 @@
main(int argc, char **argv)
{
char *repo, cmd[32], buf[512];
- char *user;
Conn c;
ARGBEGIN{
@@ -510,9 +508,6 @@
if(*pathpfx != '/')
sysfatal("path prefix must begin with '/'");
break;
- case 'n':
- namespace=EARGF(usage());
- break;
case 'w':
allowwrite++;
break;
@@ -522,14 +517,13 @@
}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");