ref: 189059cc9a4f0570e25c4d580379c4119f371a06
parent: ac432ac824be5dea58ede0858f80820da6933ca4
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Feb 25 14:35:04 EST 2020
Improve file-filtered git/log, tweak git/query This commmit makes several changes to improve git/log, which now reliably and cleanly will show differences. The following flags are changed: -b is now -c: this is done for consistency with other commands. -s is new: Shows a short git summary. Git/query also got changed: It now shows the zero hash as the parent of the first git commit, instead of giving an error.
--- a/fs.c
+++ b/fs.c
@@ -226,25 +226,6 @@
}
}
-/* FIXME: walk to the appropriate submodule.. */
-static Object*
-emptydir(Dirent *e)
-{
- Object *m;
-
- m = emalloc(sizeof(Object));
- m->hash = e->h;
- m->type = GTree;
- m->tree = emalloc(sizeof(Tree));
- m->tree->ent = nil;
- m->tree->nent = 0;
- m->flag |= Cloaded|Cparsed;
- m->off = -1;
- ref(m);
- cache(m);
- return m;
-}
-
static int
gtreegen(int i, Dir *d, void *p)
{
@@ -260,7 +241,7 @@
if(i >= e->tree->nent)
return -1;
if(e->tree->ent[i].ismod)
- o = emptydir(&e->tree->ent[i]);
+ o = emptydir();
else if((o = readobject(e->tree->ent[i].h)) == nil)
die("could not read object %H: %r", e->tree->ent[i].h, e->hash);
if(e->tree->ent[i].islink)
@@ -489,7 +470,7 @@
m = o->tree->ent[i].mode;
w = readobject(o->tree->ent[i].h);
if(!w && o->tree->ent[i].ismod)
- w = emptydir(&o->tree->ent[i]);
+ w = emptydir();
if(w && o->tree->ent[i].islink)
if((l = walklink(aux, w->data, w->size, 1, &m)) != nil)
w = l;
@@ -511,7 +492,7 @@
assert(qdir == Qcommit || qdir == Qobject || qdir == Qcommittree || qdir == Qhead);
if(strcmp(name, "msg") == 0)
q->path = qpath(p, 0, o->id, Qcommitmsg);
- else if(strcmp(name, "parent") == 0 && o->commit->nparent != 0)
+ else if(strcmp(name, "parent") == 0)
q->path = qpath(p, 1, o->id, Qcommitparent);
else if(strcmp(name, "hash") == 0)
q->path = qpath(p, 2, o->id, Qcommithash);
--- a/git.1
+++ b/git.1
@@ -83,10 +83,15 @@
.PP
.B git/log
[
-.B -b
-.I branch
+.B -c
+.I commit
+.B | -q
+.I query
]
[
+.B -s
+]
+[
.I files...
]
.PP
@@ -283,6 +288,19 @@
.PP
.B Git/log
shows a history of the current branch.
+When passed a list of files, only commits affecting
+those files are shown.
+The
+.I -c commit
+option logs starting from the provided commit, instead of HEAD.
+The
+.I -s
+option shows a summary of the commit, instead of the full message.
+The
+.I -q query
+option shows commits matching the query provided. The query
+is specified using the syntax of
+.B git/query.
.PP
.B Git/diff
--- a/git.h
+++ b/git.h
@@ -229,6 +229,7 @@
Object *ref(Object *);
void unref(Object *);
void cache(Object *);
+Object *emptydir(void);
/* object sets */
void osinit(Objset *);
--- a/log
+++ b/log
@@ -3,7 +3,7 @@
. /sys/lib/git/common.rc
usage='
- git/log [-q query] [file ...]
+ git/log [-q query|-c commit] [-s] [file ...]
'
gitup
@@ -11,15 +11,18 @@
base=/mnt/git/object/
branch=`{git/branch}
query=()
-
+short=()
+files=()
while(~ $1 -* && ! ~ $1 --){
switch($1){
- case -b
- branch=$2
+ case -c
+ base=$2
shift
case -q
query=$2
shift
+ case -s
+ short=true
case *
usage
}
@@ -31,29 +34,34 @@
commits=`{git/query $branch}
if not
commits=`{git/query $query}
-files=()
+
if(! ~ $#* 0)
- files=`$nl{walk -f $*}
+ files=`"{walk -f $gitrel^$* | sort}
-if(! ~ $#files 0)
- nids=`{sha1sum $base/$commits(1)^/tree/$files | awk '{print $1}' >[2]/dev/null}
-
while(! ~ $#commits 0){
ids=$nids
+ show=()
c=$commits(1)
- if(! ~ $#files 0)
- nids=`{sha1sum $base/$commits(1)^/tree/$files | awk '{print $1}' >[2]/dev/null}
- commits=$commits(2-)
- if(~ $#query 0)
- commits=($commits `{cat $base/$c/parent >[2]/dev/null})
+ if(! ~ $#files 0){
+ ncomm=`{comm -12 /env/files <{git/query -c $c~ $c | sed 's/^..//' | sort} | wc -l}
+ if(! ~ $ncomm 0)
+ show=true
+ }
+ commits=$commits(2-)
+ if(~ $#query 0)
+ commits=($commits `{cat $base/$c/parent >[2]/dev/null})
if(! ~ $#commits 0)
commits=`$nl{walk -emp -n0 $base^$commits | sort -rn | uniq | awk -F/ '{print $NF}'}
- if(~ $#files 0 || ! ~ $"ids $"nids || ~ $#commits 0){
- echo -n 'Hash: '`''{cat $base/$c/hash}
- echo -n 'Author: '`''{cat $base/$c/author}
- echo -n 'Date: '`''{date `{mtime $base/$c/msg | awk '{print $1}'}}
- sed 's/^/ /g' $base/$c/msg
- echo
+ if(~ $#files 0 || ~ $show true){
+ if(~ $short true)
+ echo $c `{cat $base/$c/msg | sed 1q}
+ if not{
+ echo -n 'Hash: '`''{cat $base/$c/hash}
+ echo -n 'Author: '`''{cat $base/$c/author}
+ echo -n 'Date: '`''{date `{mtime $base/$c/msg | awk '{print $1}'}}
+ sed 's/^/ /g' $base/$c/msg
+ echo
+ }
}
}
--- a/query.c
+++ b/query.c
@@ -62,6 +62,7 @@
Object *a, *b;
int c;
+
if((a = readobject(ah)) == nil)
sysfatal("bad hash %H", ah);
if((b = readobject(bh)) == nil)
--- a/ref.c
+++ b/ref.c
@@ -220,10 +220,13 @@
o = pop(ev);
/* Special case: first commit has no parent. */
- if(o->commit->nparent == 0 || (p = readobject(o->commit->parent[0])) == nil){
+ if(o->commit->nparent == 0)
+ p = emptydir();
+ else if ((p = readobject(o->commit->parent[0])) == nil){
werrstr("no parent for %H", o->hash);
return -1;
}
+
push(ev, p);
return 0;
}
--- a/save.c
+++ b/save.c
@@ -14,16 +14,6 @@
Maxparents = 16,
};
-Object*
-emptydir(void)
-{
- Object *t;
-
- t = emalloc(sizeof(Object));
- t->tree = emalloc(sizeof(Tinfo));
- return t;
-}
-
int
gitmode(int m)
{
--- a/util.c
+++ b/util.c
@@ -7,6 +7,26 @@
Reprog *authorpat;
Hash Zhash;
+Object*
+emptydir(void)
+{
+ static Object *e;
+
+ if(e != nil)
+ return e;
+ e = emalloc(sizeof(Object));
+ e->hash = Zhash;
+ e->type = GTree;
+ e->tree = emalloc(sizeof(Tinfo));
+ e->tree->ent = nil;
+ e->tree->nent = 0;
+ e->flag |= Cloaded|Cparsed;
+ e->off = -1;
+ ref(e);
+ cache(e);
+ return e;
+}
+
int
hasheq(Hash *a, Hash *b)
{