Skip to content

Commit

Permalink
Make "rev-tree" able to read its own output again from the cache.
Browse files Browse the repository at this point in the history
Also, add "date" information to the output so that you can do something
like this:

	rev-tree `cat .git/HEAD` | sort -nr | cut -d' ' -f2 | while read i; do cat-file commit $i; done

which basically becomes a "git log" (aka "git changes") where things are
sorted by time.
  • Loading branch information
Linus Torvalds committed Apr 12, 2005
1 parent 727ff27 commit 40e88b9
Showing 1 changed file with 74 additions and 7 deletions.
81 changes: 74 additions & 7 deletions rev-tree.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#define _XOPEN_SOURCE /* glibc2 needs this */
#include <time.h>
#include <ctype.h>
#include "cache.h"

/*
Expand All @@ -24,6 +27,7 @@ struct parent {
struct revision {
unsigned int flags;
unsigned char sha1[20];
unsigned long date;
struct parent *parent;
};

Expand Down Expand Up @@ -97,6 +101,52 @@ static int add_relationship(struct revision *rev, unsigned char *parent_sha)
return 1;
}

static unsigned long parse_time(const char *buf)
{
char c, *p;
char buffer[100];
struct tm tm;
const char *formats[] = {
"%c",
"%a %b %d %T %y",
NULL
};
const char **fmt = formats;

p = buffer;
while (isspace(c = *buf))
buf++;
while ((c = *buf++) != '\n')
*p++ = c;
*p++ = 0;
buf = buffer;
memset(&tm, 0, sizeof(tm));
do {
const char *next = strptime(buf, *fmt, &tm);
fmt++;
if (next) {
if (!*next)
return mktime(&tm);
buf = next;
}
} while (*buf && *fmt);
return mktime(&tm);
}


static unsigned long parse_commit_date(const char *buf)
{
if (memcmp(buf, "author", 6))
return 0;
while (*buf++ != '\n')
/* nada */;
if (memcmp(buf, "committer", 9))
return 0;
while (*buf++ != '>')
/* nada */;
return parse_time(buf);
}

static int parse_commit(unsigned char *sha1)
{
struct revision *rev = lookup_rev(sha1);
Expand All @@ -117,27 +167,44 @@ static int parse_commit(unsigned char *sha1)
parse_commit(parent);
buffer += 48; /* "parent " + "hex sha1" + "\n" */
}
rev->date = parse_commit_date(buffer);
free(buffer);
}
return 0;
}

static void read_cache_file(const char *path)
{
FILE *file = fopen(path, "r");
char line[100];
char line[500];

if (!file)
usage("bad revtree cache file (%s)", path);

while (fgets(line, sizeof(line), file)) {
unsigned char sha1[20], parent[20];
unsigned long date;
unsigned char sha1[20];
struct revision *rev;

if (get_sha1_hex(line, sha1) || get_sha1_hex(line + 41, parent))
usage("bad rev-tree cache file %s", path);
const char *buf;

if (sscanf(line, "%lu", &date) != 1)
break;
buf = strchr(line, ' ');
if (!buf)
break;
if (get_sha1_hex(buf+1, sha1))
break;
rev = lookup_rev(sha1);
rev->flags |= SEEN;
add_relationship(rev, parent);
rev->date = date;

/* parents? */
while ((buf = strchr(buf+1, ' ')) != NULL) {
unsigned char parent[20];
if (get_sha1_hex(buf + 1, parent))
break;
add_relationship(rev, parent);
}
}
fclose(file);
}
Expand Down Expand Up @@ -244,7 +311,7 @@ int main(int argc, char **argv)
if (!interesting(rev))
continue;

printf("%s:%d", sha1_to_hex(rev->sha1), marked(rev));
printf("%lu %s:%d", rev->date, sha1_to_hex(rev->sha1), marked(rev));
p = rev->parent;
while (p) {
printf(" %s:%d", sha1_to_hex(p->parent->sha1), marked(p->parent));
Expand Down

0 comments on commit 40e88b9

Please sign in to comment.