diff --git a/sys/man/1/git b/sys/man/1/git index 6315fc1b3..42909e30e 100644 --- a/sys/man/1/git +++ b/sys/man/1/git @@ -183,6 +183,10 @@ git/pull, git/rm, git/serve \- Manage git repositories. .I filters ] [ +.B -r +.I rel +] +[ .I file... ] @@ -331,7 +335,14 @@ is an alias for .PP .B Git/commit creates a new commit consisting of all changes to the specified files. -By default, an editor is opened to prepare the commit message. +By default, +.I $editor +is opened to prepare the commit message. +If +.I $editor +is undefined +.IR hold (1) +is used. The .B -m flag supplies the commit message directly. @@ -532,6 +543,10 @@ The .B -q option suppresses all output. The +.B -r +option causes paths to be printed relative to the supplied directory +.IR rel . +The .B -f option filters files by status, and only matching items are printed. By default, the filters are diff --git a/sys/src/cmd/git/diff b/sys/src/cmd/git/diff index db5df757e..840926f9e 100755 --- a/sys/src/cmd/git/diff +++ b/sys/src/cmd/git/diff @@ -21,7 +21,7 @@ if(! ~ $#* 0) branch=`{git/query -p $commit} if(~ $summarize 1 || ~ $uncommitted 1){ - git/walk -f$filt $cparam $files + git/walk -r$gitrel -f$filt $cparam $files exit } diff --git a/sys/src/cmd/git/walk.c b/sys/src/cmd/git/walk.c index 9f8cfe482..0c81aeda9 100644 --- a/sys/src/cmd/git/walk.c +++ b/sys/src/cmd/git/walk.c @@ -33,6 +33,9 @@ Seen seentab[NCACHE]; Idxed idxtab[NCACHE]; char repopath[1024]; char wdirpath[1024]; +char relapath[1024]; +char slashes[1024]; +int nslash; char *rstr = "R "; char *mstr = "M "; char *astr = "A "; @@ -347,15 +350,58 @@ reporel(char *s) void show(Biobuf *o, int flg, char *str, char *path) { + char *pa, *pb, *suffix; + int ncommon = 0; + dirty |= flg; - if(!quiet && (printflg & flg)) - Bprint(o, "%s%s\n", str, path); + if(!quiet && (printflg & flg)){ + if(nslash){ + suffix = path; + for(pa = relapath, pb = path; *pa && *pb; pa++, pb++){ + if(*pa != *pb) + break; + if(*pa == '/'){ + ncommon++; + suffix = pb+1; + } + } + Bprint(o, "%s%.*s%s\n", str, (nslash-ncommon)*3, slashes, suffix); + } else + Bprint(o, "%s%s\n", str, path); + } +} + +void +findslashes(char *path) +{ + char *s, *p; + + p = cleanname(path); + if(p[0] == '.'){ + if(p[1] == '\0') + return; + else if(p[1] == '.' && (p[2] == '/' || p[2] == '\0')) + sysfatal("relative path escapes git root"); + } + + snprint(relapath, sizeof relapath, "%s/", p); + p = relapath; + if(*p == '/') + p++; + + s = slashes; + for(; *p; p++){ + if(*p != '/') + continue; + nslash++; + s = seprint(s, slashes + sizeof slashes, "../"); + } } void usage(void) { - fprint(2, "usage: %s [-qbc] [-f filt] [-b base] [paths...]\n", argv0); + fprint(2, "usage: %s [-qbc] [-f filt] [-b base] [-r rel] [paths...]\n", argv0); exits("usage"); } @@ -410,6 +456,9 @@ main(int argc, char **argv) useidx = 1; bdir = smprint(".git/fs/object/%H/tree", h); break; + case 'r': + findslashes(EARGF(usage())); + break; default: usage(); }ARGEND;