Browse Source
It was one of those things that were well intentioned but did not turn out to be useful in practice. Signed-off-by: Junio C Hamano <junkio@cox.net>maint
Junio C Hamano
20 years ago
12 changed files with 4 additions and 558 deletions
@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
|
||||
git-build-rev-cache(1) |
||||
====================== |
||||
|
||||
NAME |
||||
---- |
||||
git-build-rev-cache - Create or update a rev-cache file. |
||||
|
||||
SYNOPSIS |
||||
-------- |
||||
'git-build-rev-cache' [-v] <rev-cache-file> < list-of-heads |
||||
|
||||
DESCRIPTION |
||||
----------- |
||||
Creates or updates a file that describes the commit ancestry reachable |
||||
from the list-of-head read from stdin. This file is in an append-only |
||||
binary format to make the server side friendly to rsync mirroring |
||||
scheme, and can be read by the git-show-rev-cache command. |
||||
|
||||
OPTIONS |
||||
------- |
||||
-v:: |
||||
Verbose. |
||||
|
||||
<rev-cache-file>:: |
||||
The rev-cache to operate on. |
||||
|
||||
Author |
||||
------ |
||||
Written by Junio C Hamano <junkio@cox.net> |
||||
|
||||
Documentation |
||||
-------------- |
||||
Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>. |
||||
|
||||
GIT |
||||
--- |
||||
Part of the link:git.html[git] suite |
||||
|
@ -1,37 +0,0 @@
@@ -1,37 +0,0 @@
|
||||
git-show-rev-cache(1) |
||||
===================== |
||||
|
||||
NAME |
||||
---- |
||||
git-show-rev-cache - Show the contents of a rev-cache file. |
||||
|
||||
SYNOPSIS |
||||
-------- |
||||
'git-show-rev-cache' <rev-cache-file> |
||||
|
||||
DESCRIPTION |
||||
----------- |
||||
Show the contents of <rev-cache-file>. |
||||
|
||||
A rev-cache file describes the commit ancestry reachable from references |
||||
supplied as input to get-build-rev-cache. This file is in an |
||||
append-only binary format to make the server side friendly to rsync |
||||
mirroring scheme. |
||||
|
||||
OPTIONS |
||||
------- |
||||
<rev-cache-file>:: |
||||
Rev-cache file to display. |
||||
|
||||
Author |
||||
------ |
||||
Written by Junio C Hamano <junkio@cox.net> |
||||
|
||||
Documentation |
||||
-------------- |
||||
Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>. |
||||
|
||||
GIT |
||||
--- |
||||
Part of the link:git.html[git] suite |
||||
|
@ -1,56 +0,0 @@
@@ -1,56 +0,0 @@
|
||||
#include "refs.h" |
||||
#include "cache.h" |
||||
#include "commit.h" |
||||
#include "rev-cache.h" |
||||
|
||||
static void process_head_list(int verbose) |
||||
{ |
||||
char buf[512]; |
||||
|
||||
while (fgets(buf, sizeof(buf), stdin)) { |
||||
unsigned char sha1[20]; |
||||
struct commit *commit; |
||||
|
||||
if (get_sha1_hex(buf, sha1)) { |
||||
error("ignoring: %s", buf); |
||||
continue; |
||||
} |
||||
if (!(commit = lookup_commit_reference(sha1))) { |
||||
error("not a commit: %s", sha1_to_hex(sha1)); |
||||
continue; |
||||
} |
||||
record_rev_cache(commit->object.sha1, verbose ? stderr : NULL); |
||||
} |
||||
} |
||||
|
||||
|
||||
static const char *build_rev_cache_usage = |
||||
"git-build-rev-cache <rev-cache-file> < list-of-heads"; |
||||
|
||||
int main(int ac, char **av) |
||||
{ |
||||
int verbose = 0; |
||||
const char *path; |
||||
|
||||
while (1 < ac && av[1][0] == '-') { |
||||
if (!strcmp(av[1], "-v")) |
||||
verbose = 1; |
||||
else |
||||
usage(build_rev_cache_usage); |
||||
ac--; av++; |
||||
} |
||||
|
||||
if (ac != 2) |
||||
usage(build_rev_cache_usage); |
||||
|
||||
path = av[1]; |
||||
|
||||
/* read existing rev-cache */ |
||||
read_rev_cache(path, NULL, 0); |
||||
|
||||
process_head_list(verbose); |
||||
|
||||
/* update the rev-cache database by appending newly found one to it */ |
||||
write_rev_cache(path, path); |
||||
return 0; |
||||
} |
@ -1,318 +0,0 @@
@@ -1,318 +0,0 @@
|
||||
#include "refs.h" |
||||
#include "cache.h" |
||||
#include "rev-cache.h" |
||||
|
||||
struct rev_cache **rev_cache; |
||||
int nr_revs, alloc_revs; |
||||
|
||||
static struct rev_list_elem *rle_free; |
||||
|
||||
#define BATCH_SIZE 512 |
||||
|
||||
int find_rev_cache(const unsigned char *sha1) |
||||
{ |
||||
int lo = 0, hi = nr_revs; |
||||
while (lo < hi) { |
||||
int mi = (lo + hi) / 2; |
||||
struct rev_cache *ri = rev_cache[mi]; |
||||
int cmp = memcmp(sha1, ri->sha1, 20); |
||||
if (!cmp) |
||||
return mi; |
||||
if (cmp < 0) |
||||
hi = mi; |
||||
else |
||||
lo = mi + 1; |
||||
} |
||||
return -lo - 1; |
||||
} |
||||
|
||||
static struct rev_list_elem *alloc_list_elem(void) |
||||
{ |
||||
struct rev_list_elem *rle; |
||||
if (!rle_free) { |
||||
int i; |
||||
|
||||
rle = xmalloc(sizeof(*rle) * BATCH_SIZE); |
||||
for (i = 0; i < BATCH_SIZE - 1; i++) { |
||||
rle[i].ri = NULL; |
||||
rle[i].next = &rle[i + 1]; |
||||
} |
||||
rle[BATCH_SIZE - 1].ri = NULL; |
||||
rle[BATCH_SIZE - 1].next = NULL; |
||||
rle_free = rle; |
||||
} |
||||
rle = rle_free; |
||||
rle_free = rle->next; |
||||
return rle; |
||||
} |
||||
|
||||
static struct rev_cache *create_rev_cache(const unsigned char *sha1) |
||||
{ |
||||
struct rev_cache *ri; |
||||
int pos = find_rev_cache(sha1); |
||||
|
||||
if (0 <= pos) |
||||
return rev_cache[pos]; |
||||
pos = -pos - 1; |
||||
if (alloc_revs <= ++nr_revs) { |
||||
alloc_revs = alloc_nr(alloc_revs); |
||||
rev_cache = xrealloc(rev_cache, sizeof(ri) * alloc_revs); |
||||
} |
||||
if (pos < nr_revs) |
||||
memmove(rev_cache + pos + 1, rev_cache + pos, |
||||
(nr_revs - pos - 1) * sizeof(ri)); |
||||
ri = xcalloc(1, sizeof(*ri)); |
||||
memcpy(ri->sha1, sha1, 20); |
||||
rev_cache[pos] = ri; |
||||
return ri; |
||||
} |
||||
|
||||
static unsigned char last_sha1[20]; |
||||
|
||||
static void write_one_rev_cache(FILE *rev_cache_file, struct rev_cache *ri) |
||||
{ |
||||
unsigned char flag; |
||||
struct rev_list_elem *rle; |
||||
|
||||
if (ri->written) |
||||
return; |
||||
|
||||
if (ri->parsed) { |
||||
/* We use last_sha1 compression only for the first parent; |
||||
* otherwise the resulting rev-cache would lose the parent |
||||
* order information. |
||||
*/ |
||||
if (ri->parents && |
||||
!memcmp(ri->parents->ri->sha1, last_sha1, 20)) |
||||
flag = (ri->num_parents - 1) | 0x80; |
||||
else |
||||
flag = ri->num_parents; |
||||
|
||||
fwrite(ri->sha1, 20, 1, rev_cache_file); |
||||
fwrite(&flag, 1, 1, rev_cache_file); |
||||
for (rle = ri->parents; rle; rle = rle->next) { |
||||
if (flag & 0x80 && rle == ri->parents) |
||||
continue; |
||||
fwrite(rle->ri->sha1, 20, 1, rev_cache_file); |
||||
} |
||||
memcpy(last_sha1, ri->sha1, 20); |
||||
ri->written = 1; |
||||
} |
||||
/* recursively write children depth first */ |
||||
for (rle = ri->children; rle; rle = rle->next) |
||||
write_one_rev_cache(rev_cache_file, rle->ri); |
||||
} |
||||
|
||||
void write_rev_cache(const char *newpath, const char *oldpath) |
||||
{ |
||||
/* write the following commit ancestry information in |
||||
* $GIT_DIR/info/rev-cache. |
||||
* |
||||
* The format is: |
||||
* 20-byte SHA1 (commit ID) |
||||
* 1-byte flag: |
||||
* - bit 0-6 records "number of parent commit SHA1s to |
||||
* follow" (i.e. up to 127 children can be listed). |
||||
* - when the bit 7 is on, then "the entry immediately |
||||
* before this entry is one of the parents of this |
||||
* commit". |
||||
* N x 20-byte SHA1 (parent commit IDs) |
||||
*/ |
||||
FILE *rev_cache_file; |
||||
int i; |
||||
struct rev_cache *ri; |
||||
|
||||
if (!strcmp(newpath, oldpath)) { |
||||
/* If we are doing it in place */ |
||||
rev_cache_file = fopen(newpath, "a"); |
||||
} |
||||
else { |
||||
char buf[8096]; |
||||
size_t sz; |
||||
FILE *oldfp = fopen(oldpath, "r"); |
||||
rev_cache_file = fopen(newpath, "w"); |
||||
if (oldfp) { |
||||
while (1) { |
||||
sz = fread(buf, 1, sizeof(buf), oldfp); |
||||
if (sz == 0) |
||||
break; |
||||
fwrite(buf, 1, sz, rev_cache_file); |
||||
} |
||||
fclose(oldfp); |
||||
} |
||||
} |
||||
|
||||
memset(last_sha1, 0, 20); |
||||
|
||||
/* Go through available rev_cache structures, starting from |
||||
* parentless ones first, so that we would get most out of |
||||
* last_sha1 optimization by the depth first behaviour of |
||||
* write_one_rev_cache(). |
||||
*/ |
||||
for (i = 0; i < nr_revs; i++) { |
||||
ri = rev_cache[i]; |
||||
if (ri->num_parents) |
||||
continue; |
||||
write_one_rev_cache(rev_cache_file, ri); |
||||
} |
||||
/* Then the rest */ |
||||
for (i = 0; i < nr_revs; i++) { |
||||
ri = rev_cache[i]; |
||||
write_one_rev_cache(rev_cache_file, ri); |
||||
} |
||||
fclose(rev_cache_file); |
||||
} |
||||
|
||||
static void add_parent(struct rev_cache *child, |
||||
const unsigned char *parent_sha1) |
||||
{ |
||||
struct rev_cache *parent = create_rev_cache(parent_sha1); |
||||
struct rev_list_elem *e = alloc_list_elem(); |
||||
|
||||
/* Keep the parent list ordered in the same way the commit |
||||
* object records them. |
||||
*/ |
||||
e->ri = parent; |
||||
e->next = NULL; |
||||
if (!child->parents_tail) |
||||
child->parents = e; |
||||
else |
||||
child->parents_tail->next = e; |
||||
child->parents_tail = e; |
||||
child->num_parents++; |
||||
|
||||
/* There is no inherent order of the children so we just |
||||
* LIFO them together. |
||||
*/ |
||||
e = alloc_list_elem(); |
||||
e->next = parent->children; |
||||
parent->children = e; |
||||
e->ri = child; |
||||
parent->num_children++; |
||||
} |
||||
|
||||
int read_rev_cache(const char *path, FILE *dumpfile, int dry_run) |
||||
{ |
||||
unsigned char *map; |
||||
int fd; |
||||
struct stat st; |
||||
unsigned long ofs, len; |
||||
struct rev_cache *ri = NULL; |
||||
|
||||
fd = open(path, O_RDONLY); |
||||
if (fd < 0) { |
||||
if (dry_run) |
||||
return error("cannot open %s", path); |
||||
if (errno == ENOENT) |
||||
return 0; |
||||
return -1; |
||||
} |
||||
if (fstat(fd, &st)) { |
||||
close(fd); |
||||
return -1; |
||||
} |
||||
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
||||
close(fd); |
||||
if (map == MAP_FAILED) |
||||
return -1; |
||||
|
||||
memset(last_sha1, 0, 20); |
||||
ofs = 0; |
||||
len = st.st_size; |
||||
while (ofs < len) { |
||||
unsigned char sha1[20]; |
||||
int flag, cnt, i; |
||||
if (len < ofs + 21) |
||||
die("rev-cache too short"); |
||||
memcpy(sha1, map + ofs, 20); |
||||
flag = map[ofs + 20]; |
||||
ofs += 21; |
||||
cnt = (flag & 0x7f) + ((flag & 0x80) != 0); |
||||
if (len < ofs + (flag & 0x7f) * 20) |
||||
die("rev-cache too short to have %d more parents", |
||||
(flag & 0x7f)); |
||||
if (dumpfile) |
||||
fprintf(dumpfile, "%s", sha1_to_hex(sha1)); |
||||
if (!dry_run) { |
||||
ri = create_rev_cache(sha1); |
||||
if (!ri) |
||||
die("cannot create rev-cache for %s", |
||||
sha1_to_hex(sha1)); |
||||
ri->written = ri->parsed = 1; |
||||
} |
||||
i = 0; |
||||
if (flag & 0x80) { |
||||
if (!dry_run) |
||||
add_parent(ri, last_sha1); |
||||
if (dumpfile) |
||||
fprintf(dumpfile, " %s", |
||||
sha1_to_hex(last_sha1)); |
||||
i++; |
||||
} |
||||
while (i++ < cnt) { |
||||
if (!dry_run) |
||||
add_parent(ri, map + ofs); |
||||
if (dumpfile) |
||||
fprintf(dumpfile, " %s", |
||||
sha1_to_hex(last_sha1)); |
||||
ofs += 20; |
||||
} |
||||
if (dumpfile) |
||||
fprintf(dumpfile, "\n"); |
||||
memcpy(last_sha1, sha1, 20); |
||||
} |
||||
if (ofs != len) |
||||
die("rev-cache truncated?"); |
||||
munmap(map, len); |
||||
return 0; |
||||
} |
||||
|
||||
int record_rev_cache(const unsigned char *sha1, FILE *dumpfile) |
||||
{ |
||||
unsigned char parent[20]; |
||||
char type[20]; |
||||
unsigned long size, ofs; |
||||
unsigned int cnt, i; |
||||
void *buf; |
||||
struct rev_cache *ri; |
||||
|
||||
buf = read_sha1_file(sha1, type, &size); |
||||
if (!buf) |
||||
return error("%s: not found", sha1_to_hex(sha1)); |
||||
if (strcmp(type, "commit")) { |
||||
free(buf); |
||||
return error("%s: not a commit but a %s", |
||||
sha1_to_hex(sha1), type); |
||||
} |
||||
ri = create_rev_cache(sha1); |
||||
if (ri->parsed) |
||||
return 0; |
||||
if (dumpfile) |
||||
fprintf(dumpfile, "commit %s\n", sha1_to_hex(sha1)); |
||||
|
||||
cnt = 0; |
||||
ofs = 46; /* "tree " + hex-sha1 + "\n" */ |
||||
while (!memcmp(buf + ofs, "parent ", 7) && |
||||
!get_sha1_hex(buf + ofs + 7, parent)) { |
||||
ofs += 48; |
||||
cnt++; |
||||
} |
||||
if (cnt * 48 + 46 != ofs) { |
||||
free(buf); |
||||
die("internal error in record_rev_cache"); |
||||
} |
||||
|
||||
ri = create_rev_cache(sha1); |
||||
ri->parsed = 1; |
||||
|
||||
for (i = 0; i < cnt; i++) { |
||||
unsigned char parent_sha1[20]; |
||||
|
||||
ofs = 46 + i * 48 + 7; |
||||
get_sha1_hex(buf + ofs, parent_sha1); |
||||
add_parent(ri, parent_sha1); |
||||
record_rev_cache(parent_sha1, dumpfile); |
||||
} |
||||
free(buf); |
||||
return 0; |
||||
} |
@ -1,29 +0,0 @@
@@ -1,29 +0,0 @@
|
||||
#ifndef REV_CACHE_H |
||||
#define REV_CACHE_H |
||||
|
||||
extern struct rev_cache { |
||||
struct rev_cache *head_list; |
||||
struct rev_list_elem *children; |
||||
struct rev_list_elem *parents; |
||||
struct rev_list_elem *parents_tail; |
||||
unsigned short num_parents; |
||||
unsigned short num_children; |
||||
unsigned int written : 1; |
||||
unsigned int parsed : 1; |
||||
unsigned int work : 30; |
||||
void *work_ptr; |
||||
unsigned char sha1[20]; |
||||
} **rev_cache; |
||||
extern int nr_revs, alloc_revs; |
||||
|
||||
struct rev_list_elem { |
||||
struct rev_list_elem *next; |
||||
struct rev_cache *ri; |
||||
}; |
||||
|
||||
extern int find_rev_cache(const unsigned char *); |
||||
extern int read_rev_cache(const char *, FILE *, int); |
||||
extern int record_rev_cache(const unsigned char *, FILE *); |
||||
extern void write_rev_cache(const char *new, const char *old); |
||||
|
||||
#endif |
@ -1,18 +0,0 @@
@@ -1,18 +0,0 @@
|
||||
#include "cache.h" |
||||
#include "rev-cache.h" |
||||
|
||||
static char *show_rev_cache_usage = |
||||
"git-show-rev-cache <rev-cache-file>"; |
||||
|
||||
int main(int ac, char **av) |
||||
{ |
||||
while (1 < ac && av[0][1] == '-') { |
||||
/* do flags here */ |
||||
break; |
||||
ac--; av++; |
||||
} |
||||
if (ac != 2) |
||||
usage(show_rev_cache_usage); |
||||
|
||||
return read_rev_cache(av[1], stdout, 1); |
||||
} |
Loading…
Reference in new issue