]> git.lizzy.rs Git - plan9front.git/commitdiff
git: allow local repository directories as remote uri's
authorcinap_lenrek <cinap_lenrek@felloff.net>
Fri, 4 Jun 2021 15:47:26 +0000 (17:47 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Fri, 4 Jun 2021 15:47:26 +0000 (17:47 +0200)
This is implemented by checking first if the uri is
a directory containing the .git/ subdirectory.
If this is the case, we fork git/serve serving the
repository on a pipe.

sys/src/cmd/git/proto.c

index 19c0889affbfc0a8056663e68547a7fa00a716b4..1611a2abe6f67658523ec882df04b95005c2d4db 100644 (file)
@@ -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)