git: make git/diff -s print relative file paths

This makes the output of git/diff -s plumbable
when the user is not within the root of the git repo.
This is implemented through adding a flag to git/walk
and having git/walk work out how many '..'s are needed.

Also includes a small piece of documentation regarding
the use of $editor in git/commit.
This commit is contained in:
Jacob Moody 2024-12-22 21:06:53 +00:00
parent 35cab9b816
commit 7814ec46c3
3 changed files with 69 additions and 5 deletions

View file

@ -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

View file

@ -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
}

View file

@ -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;