ref: 7814ec46c39671d5c0721626c52c6d86c21cb311
parent: 35cab9b816dbf6eabe94d4ed3eff01ebff68a695
author: Jacob Moody <moody@posixcafe.org>
date: Sun Dec 22 16:06:53 EST 2024
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.
--- a/sys/man/1/git
+++ b/sys/man/1/git
@@ -183,6 +183,10 @@
.I filters
]
[
+.B -r
+.I rel
+]
+[
.I file...
]
@@ -331,7 +335,14 @@
.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.
@@ -531,6 +542,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.
--- a/sys/src/cmd/git/diff
+++ b/sys/src/cmd/git/diff
@@ -21,7 +21,7 @@
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
}
--- a/sys/src/cmd/git/walk.c
+++ b/sys/src/cmd/git/walk.c
@@ -33,6 +33,9 @@
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 @@
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");
}
@@ -409,6 +455,9 @@
if(resolveref(&hd, "HEAD") == 0 && hasheq(&h, &hd))
useidx = 1;
bdir = smprint(".git/fs/object/%H/tree", h);
+ break;
+ case 'r':
+ findslashes(EARGF(usage()));
break;
default:
usage();
--
⑨