* [PATCH 11/19] migrate write-tree.c to use the new cache api's
From: Brad Roberts @ 2005-04-21 18:37 UTC (permalink / raw)
To: git
tree 3a2928786f84d81cfb1a5846cdaf9f3d5403cbcf
parent a94803645fb68119be8835d466585c91e664a173
author Brad Roberts <braddr@puremagic.com> 1114077713 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114077713 -0700
[PATCH] migrate write-tree.c to use the new cache api's
Along the way, altered the write_tree recursion to stay based off of a starting
position rather than moving the array pointer for each recurse step.
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
write-tree.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
Index: write-tree.c
===================================================================
--- a94803645fb68119be8835d466585c91e664a173:1/write-tree.c (mode:100644 sha1:827809dbddbff6dd8cf842641f6db5ad2f3ae07a)
+++ 8a4556bdf5bc847117c840a8fd7fa42f6efb16e1:1/write-tree.c (mode:100644 sha1:f1b12cdde1bb446a134a121760007150008b251a)
@@ -29,7 +29,7 @@
#define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
-static int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1)
+static int write_tree(int start_pos, const char *base, int baselen, unsigned char *returnsha1)
{
unsigned char subdir_sha1[20];
unsigned long size, offset;
@@ -43,7 +43,7 @@
nr = 0;
do {
- struct cache_entry *ce = cachep[nr];
+ struct cache_entry *ce = get_cache_entry(start_pos + nr);
const char *pathname = ce->name, *filename, *dirname;
int pathlen = ce_namelen(ce), entrylen;
unsigned char *sha1;
@@ -53,16 +53,13 @@
if (baselen >= pathlen || memcmp(base, pathname, baselen))
break;
- sha1 = ce->sha1;
- mode = ntohl(ce->ce_mode);
-
/* Do we have _further_ subdirectories? */
filename = pathname + baselen;
dirname = strchr(filename, '/');
if (dirname) {
int subdir_written;
- subdir_written = write_tree(cachep + nr, maxentries - nr, pathname, dirname-pathname+1, subdir_sha1);
+ subdir_written = write_tree(start_pos + nr, pathname, dirname-pathname+1, subdir_sha1);
nr += subdir_written;
/* Now we need to write out the directory entry into this tree.. */
@@ -72,6 +69,9 @@
/* ..but the directory entry doesn't count towards the total count */
nr--;
sha1 = subdir_sha1;
+ } else {
+ sha1 = ce->sha1;
+ mode = ntohl(ce->ce_mode);
}
if (check_valid_sha1(sha1) < 0)
@@ -87,7 +87,7 @@
memcpy(buffer + offset, sha1, 20);
offset += 20;
nr++;
- } while (nr < maxentries);
+ } while ((start_pos + nr) < get_num_cache_entries());
i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
i -= 5;
@@ -110,7 +110,7 @@
/* Verify that the tree is merged */
unmerged = 0;
for (i = 0; i < entries; i++) {
- struct cache_entry *ce = active_cache[i];
+ struct cache_entry *ce = get_cache_entry(i);
if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) {
if (++unmerged > 10) {
fprintf(stderr, "...\n");
@@ -123,7 +123,7 @@
die("write-tree: not able to write tree");
/* Ok, write it out */
- if (write_tree(active_cache, entries, "", 0, sha1) != entries)
+ if (write_tree(0, "", 0, sha1) != entries)
die("write-tree: internal error");
printf("%s\n", sha1_to_hex(sha1));
return 0;
^ permalink raw reply
* [PATCH 12/19] fix up diff-cache.c to use new cache api's
From: Brad Roberts @ 2005-04-21 18:37 UTC (permalink / raw)
To: git
tree 44f1ef88a5d0effdf2337f4c72b88b2bdcd9a54b
parent 8a4556bdf5bc847117c840a8fd7fa42f6efb16e1
author Brad Roberts <braddr@puremagic.com> 1114082996 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114082996 -0700
[PATCH] fix up diff-cache.c to use new cache api's
Along the way, rewrite to use a position index rather than pointer math.
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
diff-cache.c | 32 +++++++++++++-------------------
1 files changed, 13 insertions(+), 19 deletions(-)
Index: diff-cache.c
===================================================================
--- 8a4556bdf5bc847117c840a8fd7fa42f6efb16e1:1/diff-cache.c (mode:100644 sha1:fcbc4900d32f4ca24f67bb8f0fe344c6c5642ac9)
+++ cc414a188c0e8fefa7bea4f969cc7adfe4265d6f:1/diff-cache.c (mode:100644 sha1:548211944fc00594bfc06b9ab90f0cb476688285)
@@ -4,7 +4,7 @@
static int recursive = 0;
static int line_termination = '\n';
-static int diff_cache(void *tree, unsigned long size, struct cache_entry **ac, int entries, const char *base);
+static int diff_cache(void *tree, unsigned long size, int pos, const char *base);
static void update_tree_entry(void **bufp, unsigned long *sizep)
{
@@ -82,10 +82,10 @@
}
static int compare_tree_entry(const char *path1, unsigned int mode1, const unsigned char *sha1,
- struct cache_entry **ac, int *entries, const char *base)
+ int *pos, const char *base)
{
int baselen = strlen(base);
- struct cache_entry *ce = *ac;
+ struct cache_entry *ce = get_cache_entry(*pos);
const char *path2 = ce->name + baselen;
unsigned int mode2 = ntohl(ce->ce_mode);
const unsigned char *sha2 = ce->sha1;
@@ -107,7 +107,7 @@
memcpy(newbase + baselen + pathlen1, "/", 2);
if (!tree || strcmp(type, "tree"))
die("unable to read tree object %s", sha1_to_hex(sha1));
- *entries = diff_cache(tree, size, ac, *entries, newbase);
+ *pos = diff_cache(tree, size, *pos, newbase);
free(newbase);
free(tree);
return -1;
@@ -158,7 +158,7 @@
return 0;
}
-static int diff_cache(void *tree, unsigned long size, struct cache_entry **ac, int entries, const char *base)
+static int diff_cache(void *tree, unsigned long size, int pos, const char *base)
{
int baselen = strlen(base);
@@ -167,15 +167,16 @@
unsigned int mode;
const char *path;
const unsigned char *sha1;
- int left;
/*
* No entries in the cache (with this base)?
* Output the tree contents.
*/
- if (!entries || ce_namelen(ce = *ac) < baselen || memcmp(ce->name, base, baselen)) {
+ if ((pos == get_num_cache_entries()) ||
+ ce_namelen(ce = get_cache_entry(pos)) < baselen ||
+ memcmp(ce->name, base, baselen)) {
if (!size)
- return entries;
+ return pos;
sha1 = extract(tree, size, &path, &mode);
show_file("-", path, mode, sha1, base);
update_tree_entry(&tree, &size);
@@ -187,27 +188,20 @@
*/
if (!size) {
show_file("+", ce->name, ntohl(ce->ce_mode), ce->sha1, "");
- ac++;
- entries--;
+ pos++;
continue;
}
sha1 = extract(tree, size, &path, &mode);
- left = entries;
- switch (compare_tree_entry(path, mode, sha1, ac, &left, base)) {
+ switch (compare_tree_entry(path, mode, sha1, &pos, base)) {
case -1:
update_tree_entry(&tree, &size);
- if (left < entries) {
- ac += (entries - left);
- entries = left;
- }
continue;
case 0:
update_tree_entry(&tree, &size);
/* Fallthrough */
case 1:
- ac++;
- entries--;
+ pos++;
continue;
}
die("diff-cache: internal error");
@@ -263,5 +257,5 @@
if (strcmp(type, "tree"))
die("bad tree object %s (%s)", sha1_to_hex(tree_sha1), type);
- return diff_cache(tree, size, active_cache, active_nr, "");
+ return diff_cache(tree, size, 0, "");
}
^ permalink raw reply
* [PATCH 13/19] Remove active_cache, active_nr, and active_alloc from public view
From: Brad Roberts @ 2005-04-21 18:37 UTC (permalink / raw)
To: git
tree 9198385d73b718a2fd016362a9d93ccce1e7423c
parent cc414a188c0e8fefa7bea4f969cc7adfe4265d6f
author Brad Roberts <braddr@puremagic.com> 1114083132 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114083132 -0700
[PATCH] Remove active_cache, active_nr, and active_alloc from public view
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
cache.h | 2 --
read-cache.c | 4 ++--
2 files changed, 2 insertions(+), 4 deletions(-)
Index: cache.h
===================================================================
--- cc414a188c0e8fefa7bea4f969cc7adfe4265d6f:1/cache.h (mode:100644 sha1:74d816c34245e0dde41643188f38cf99ca75e75f)
+++ ff3667537379d5b0680e8c4f9a14d82dc9835430:1/cache.h (mode:100644 sha1:b29bb0ca5e7be15c0b423101f5cf381ee68f139e)
@@ -78,8 +78,6 @@
#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
const char *sha1_file_directory;
-struct cache_entry **active_cache;
-unsigned int active_nr, active_alloc;
#define DB_ENVIRONMENT "SHA1_FILE_DIRECTORY"
#define DEFAULT_DB_ENVIRONMENT ".git/objects"
Index: read-cache.c
===================================================================
--- cc414a188c0e8fefa7bea4f969cc7adfe4265d6f:1/read-cache.c (mode:100644 sha1:286f7136bc164f3a2317bb492138d9221efb4025)
+++ ff3667537379d5b0680e8c4f9a14d82dc9835430:1/read-cache.c (mode:100644 sha1:0e972a80fa19eb77fd547fb579354af784be3ac4)
@@ -6,8 +6,8 @@
#include <stdarg.h>
#include "cache.h"
-struct cache_entry **active_cache = NULL;
-unsigned int active_nr = 0, active_alloc = 0;
+static struct cache_entry **active_cache = NULL;
+static unsigned int active_nr = 0, active_alloc = 0;
int cache_match_stat(struct cache_entry *ce, struct stat *st)
{
^ permalink raw reply
* [PATCH 14/19] move cache_header out of the public view
From: Brad Roberts @ 2005-04-21 18:38 UTC (permalink / raw)
To: git
tree a2c82ce3512904f82f78d87d86709a471f67ef9f
parent ff3667537379d5b0680e8c4f9a14d82dc9835430
author Brad Roberts <braddr@puremagic.com> 1114083477 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114083477 -0700
[PATCH] move cache_header out of the public view
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
cache.h | 15 ---------------
read-cache.c | 11 +++++++++++
2 files changed, 11 insertions(+), 15 deletions(-)
Index: cache.h
===================================================================
--- ff3667537379d5b0680e8c4f9a14d82dc9835430:1/cache.h (mode:100644 sha1:b29bb0ca5e7be15c0b423101f5cf381ee68f139e)
+++ b7d4fa53d4ee449b4b9b4f3c9dd40d6c99db4bc1:1/cache.h (mode:100644 sha1:74d6c4d25c564e08eadc04aaef31a711d0645a43)
@@ -17,21 +17,6 @@
#include <zlib.h>
/*
- * Basic data structures for the directory cache
- *
- * NOTE NOTE NOTE! This is all in the native CPU byte format. It's
- * not even trying to be portable. It's trying to be efficient. It's
- * just a cache, after all.
- */
-
-#define CACHE_SIGNATURE 0x44495243 /* "DIRC" */
-struct cache_header {
- unsigned int hdr_signature;
- unsigned int hdr_version;
- unsigned int hdr_entries;
-};
-
-/*
* The "cache_time" is just the low 32 bits of the
* time. It doesn't matter if it overflows - we only
* check it for equality in the 32 bits we save.
Index: read-cache.c
===================================================================
--- ff3667537379d5b0680e8c4f9a14d82dc9835430:1/read-cache.c (mode:100644 sha1:0e972a80fa19eb77fd547fb579354af784be3ac4)
+++ b7d4fa53d4ee449b4b9b4f3c9dd40d6c99db4bc1:1/read-cache.c (mode:100644 sha1:b16a72dc4e4525a7df060b3a43722217db7869c2)
@@ -6,6 +6,17 @@
#include <stdarg.h>
#include "cache.h"
+/*
+ * Basic data structures for the directory cache
+ */
+
+#define CACHE_SIGNATURE 0x44495243 /* "DIRC" */
+struct cache_header {
+ unsigned int hdr_signature;
+ unsigned int hdr_version;
+ unsigned int hdr_entries;
+};
+
static struct cache_entry **active_cache = NULL;
static unsigned int active_nr = 0, active_alloc = 0;
^ permalink raw reply
* [PATCH 15/19] introduce a cache struct and move the various cache globals into it.
From: Brad Roberts @ 2005-04-21 18:38 UTC (permalink / raw)
To: git
tree c806c7328a6c9297df108ab00ebe1c4014496cb0
parent b7d4fa53d4ee449b4b9b4f3c9dd40d6c99db4bc1
author Brad Roberts <braddr@puremagic.com> 1114086327 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114086327 -0700
[PATCH] introduce a cache struct and move the various cache globals into it.
New elements in the cache struct that previously were discarded:
- the cache headers
- the mmap info so we can cleanup later
For this stage, the cache itself is still a global variable. That will change.
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
cache.h | 1
read-cache.c | 127 ++++++++++++++++++++++++++++++++++-------------------------
2 files changed, 76 insertions(+), 52 deletions(-)
Index: cache.h
===================================================================
--- b7d4fa53d4ee449b4b9b4f3c9dd40d6c99db4bc1:1/cache.h (mode:100644 sha1:74d6c4d25c564e08eadc04aaef31a711d0645a43)
+++ f07f7073f45a7f81e5b6cf26f5181e14fd051d81:1/cache.h (mode:100644 sha1:a3018f9e12bfdd1a5273b20fcab5062667c6caec)
@@ -72,6 +72,7 @@
/* Initialize and use the cache information */
extern int read_cache(void);
extern int write_cache(int newfd);
+extern void free_cache();
extern int cache_name_pos(const char *name, int namelen);
extern int add_cache_entry(struct cache_entry *ce, int ok_to_add);
extern int remove_file_from_cache(char *path);
Index: read-cache.c
===================================================================
--- b7d4fa53d4ee449b4b9b4f3c9dd40d6c99db4bc1:1/read-cache.c (mode:100644 sha1:b16a72dc4e4525a7df060b3a43722217db7869c2)
+++ f07f7073f45a7f81e5b6cf26f5181e14fd051d81:1/read-cache.c (mode:100644 sha1:c399f8e497441147afe630ca080558a8c6c79c78)
@@ -17,8 +17,20 @@
unsigned int hdr_entries;
};
-static struct cache_entry **active_cache = NULL;
-static unsigned int active_nr = 0, active_alloc = 0;
+struct mmap_holder {
+ void * ptr;
+ size_t size;
+};
+
+struct cache {
+ struct mmap_holder map;
+ struct cache_header *header;
+ struct cache_entry **entries;
+ unsigned int num_entries;
+ unsigned int allocated_entries;
+};
+
+static struct cache * cache = NULL;
int cache_match_stat(struct cache_entry *ce, struct stat *st)
{
@@ -81,10 +93,10 @@
int first, last;
first = 0;
- last = active_nr;
+ last = cache->num_entries;
while (last > first) {
int next = (last + first) >> 1;
- struct cache_entry *ce = active_cache[next];
+ struct cache_entry *ce = cache->entries[next];
int cmp = cache_name_compare(name, namelen, ce->name, htons(ce->ce_flags));
if (!cmp)
return next;
@@ -100,10 +112,10 @@
/* Remove entry, return true if there are more entries to go.. */
int remove_cache_entry_at(int pos)
{
- active_nr--;
- if (pos >= active_nr)
+ cache->num_entries--;
+ if (pos >= cache->num_entries)
return 0;
- memmove(active_cache + pos, active_cache + pos + 1, (active_nr - pos) * sizeof(struct cache_entry *));
+ memmove(cache->entries + pos, cache->entries + pos + 1, (cache->num_entries - pos) * sizeof(struct cache_entry *));
return 1;
}
@@ -123,20 +135,20 @@
int get_num_cache_entries()
{
- return active_nr;
+ return cache->num_entries;
}
struct cache_entry * get_cache_entry(int pos)
{
- return active_cache[pos];
+ return cache->entries[pos];
}
void set_cache_entry(struct cache_entry *ce, int pos)
{
- /* You can NOT just free active_cache[i] here, since it
+ /* You can NOT just free cache->entries[i] here, since it
* might not be necessarily malloc()ed but can also come
* from mmap(). */
- active_cache[pos] = ce;
+ cache->entries[pos] = ce;
}
int add_cache_entry(struct cache_entry *ce, int ok_to_add)
@@ -147,7 +159,7 @@
/* existing match? Just replace it */
if (pos >= 0) {
- active_cache[pos] = ce;
+ cache->entries[pos] = ce;
return 0;
}
pos = -pos-1;
@@ -156,8 +168,8 @@
* Inserting a merged entry ("stage 0") into the index
* will always replace all non-merged entries..
*/
- if (pos < active_nr && ce_stage(ce) == 0) {
- while (same_name(active_cache[pos], ce)) {
+ if (pos < cache->num_entries && ce_stage(ce) == 0) {
+ while (same_name(cache->entries[pos], ce)) {
ok_to_add = 1;
if (!remove_cache_entry_at(pos))
break;
@@ -168,16 +180,16 @@
return -1;
/* Make sure the array is big enough .. */
- if (active_nr == active_alloc) {
- active_alloc = alloc_nr(active_alloc);
- active_cache = realloc(active_cache, active_alloc * sizeof(struct cache_entry *));
+ if (cache->num_entries == cache->allocated_entries) {
+ cache->allocated_entries = alloc_nr(cache->allocated_entries);
+ cache->entries = realloc(cache->entries, cache->allocated_entries * sizeof(struct cache_entry *));
}
/* Add it in.. */
- active_nr++;
- if (active_nr > pos)
- memmove(active_cache + pos + 1, active_cache + pos, (active_nr - pos - 1) * sizeof(ce));
- active_cache[pos] = ce;
+ cache->num_entries++;
+ if (cache->num_entries > pos)
+ memmove(cache->entries + pos + 1, cache->entries + pos, (cache->num_entries - pos - 1) * sizeof(ce));
+ cache->entries[pos] = ce;
return 0;
}
@@ -202,12 +214,10 @@
{
int fd, i;
struct stat st;
- unsigned long size, offset;
- void *map;
- struct cache_header *hdr;
+ unsigned long offset;
errno = EBUSY;
- if (active_cache)
+ if (cache)
return error("more than one cachefile");
errno = ENOENT;
sha1_file_directory = getenv(DB_ENVIRONMENT);
@@ -219,38 +229,44 @@
if (fd < 0)
return (errno == ENOENT) ? 0 : error("open failed");
- size = 0; /* avoid gcc warning */
- map = (void *)-1;
+ errno = ENOMEM;
+ cache = (struct cache*)malloc(sizeof(struct cache));
+ if (!cache)
+ return error("unable to allocate cache");
+
+ cache->map.size = 0; /* avoid gcc warning */
+ cache->map.ptr = (void *)-1;
if (!fstat(fd, &st)) {
- size = st.st_size;
+ cache->map.size = st.st_size;
errno = EINVAL;
- if (size >= sizeof(struct cache_header) + 20)
- map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (cache->map.size >= sizeof(struct cache_header) + 20)
+ cache->map.ptr = mmap(NULL, cache->map.size, PROT_READ, MAP_PRIVATE, fd, 0);
}
close(fd);
- if (-1 == (int)(long)map)
+ if (-1 == (int)(long)cache->map.ptr) {
+ free(cache);
+ cache = NULL;
return error("mmap failed");
+ }
- hdr = map;
- if (verify_hdr(hdr, size) < 0)
- goto unmap;
-
- active_nr = ntohl(hdr->hdr_entries);
- active_alloc = alloc_nr(active_nr);
- active_cache = calloc(active_alloc, sizeof(struct cache_entry *));
-
- offset = sizeof(*hdr);
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = map + offset;
- offset = offset + ce_size(ce);
- active_cache[i] = ce;
+ cache->header = cache->map.ptr;
+ if (verify_hdr(cache->header, cache->map.size) < 0) {
+ free_cache();
+ errno = EINVAL;
+ return error("verify header failed");
}
- return active_nr;
-unmap:
- munmap(map, size);
- errno = EINVAL;
- return error("verify header failed");
+ cache->num_entries = ntohl(cache->header->hdr_entries);
+ cache->allocated_entries = alloc_nr(cache->num_entries);
+ cache->entries = calloc(cache->allocated_entries, sizeof(struct cache_entry *));
+
+ offset = sizeof(*cache->header);
+ for (i = 0; i < cache->num_entries; i++) {
+ struct cache_entry *ce = cache->map.ptr + offset;
+ offset = offset + ce_size(ce);
+ cache->entries[i] = ce;
+ }
+ return cache->num_entries;
}
#define WRITE_BUFFER_SIZE 8192
@@ -304,16 +320,23 @@
hdr.hdr_signature = htonl(CACHE_SIGNATURE);
hdr.hdr_version = htonl(2);
- hdr.hdr_entries = htonl(active_nr);
+ hdr.hdr_entries = htonl(cache->num_entries);
SHA1_Init(&c);
if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
return -1;
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
+ for (i = 0; i < cache->num_entries; i++) {
+ struct cache_entry *ce = cache->entries[i];
if (ce_write(&c, newfd, ce, ce_size(ce)) < 0)
return -1;
}
return ce_flush(&c, newfd);
}
+
+void free_cache()
+{
+ munmap(cache->map.ptr, cache->map.size);
+ free(cache);
+ cache = NULL;
+}
^ permalink raw reply
* [PATCH 16/19] change all call sites that use the return value of read_cache to get the # of cache entries.
From: Brad Roberts @ 2005-04-21 18:38 UTC (permalink / raw)
To: git
tree 6bce19032505c2939bf74eeca5e51aeefa4e1600
parent f07f7073f45a7f81e5b6cf26f5181e14fd051d81
author Brad Roberts <braddr@puremagic.com> 1114086602 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114086602 -0700
[PATCH] change all call sites that use the return value of read_cache to get the # of cache entries.
This patch somewhat breaks error handling for those call sites. I'll fix
that in the next few patches.
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
show-diff.c | 13 ++++++++-----
update-cache.c | 3 ++-
write-tree.c | 4 +++-
3 files changed, 13 insertions(+), 7 deletions(-)
Index: show-diff.c
===================================================================
--- f07f7073f45a7f81e5b6cf26f5181e14fd051d81:1/show-diff.c (mode:100644 sha1:e2642b65805b3e52a16c6309b44a92c2a2bd13c3)
+++ b965055600b8bf4927ea631446cd6cde714aef95:1/show-diff.c (mode:100644 sha1:6e04e9182667cbb79afa4c878a31b685fdea3229)
@@ -126,10 +126,17 @@
int silent_on_nonexisting_files = 0;
int machine_readable = 0;
int reverse = 0;
- int entries = read_cache();
+ int entries;
int matched = 0;
int i;
+ read_cache();
+ entries = get_num_cache_entries();
+ if (entries < 0) {
+ perror("read_cache");
+ exit(1);
+ }
+
while (1 < argc && argv[1][0] == '-') {
if (!strcmp(argv[1], "-R"))
reverse = 1;
@@ -147,10 +154,6 @@
/* At this point, if argc == 1, then we are doing everything.
* Otherwise argv[1] .. argv[argc-1] have the explicit paths.
*/
- if (entries < 0) {
- perror("read_cache");
- exit(1);
- }
prepare_diff_cmd();
for (i = 0; i < entries; i++) {
struct stat st;
Index: update-cache.c
===================================================================
--- f07f7073f45a7f81e5b6cf26f5181e14fd051d81:1/update-cache.c (mode:100644 sha1:e741f593eb9c56c596fabed7eb6b79dee2d8cba9)
+++ b965055600b8bf4927ea631446cd6cde714aef95:1/update-cache.c (mode:100644 sha1:8328975cb726f5e06a413a9f0099bfa2f81d3381)
@@ -299,7 +299,8 @@
atexit(remove_lock_file);
remove_lock = 1;
- entries = read_cache();
+ read_cache();
+ entries = get_num_cache_entries();
if (entries < 0)
die("cache corrupted");
Index: write-tree.c
===================================================================
--- f07f7073f45a7f81e5b6cf26f5181e14fd051d81:1/write-tree.c (mode:100644 sha1:f1b12cdde1bb446a134a121760007150008b251a)
+++ b965055600b8bf4927ea631446cd6cde714aef95:1/write-tree.c (mode:100644 sha1:92e707fd4780805da160ce6fa282e75111ea67b9)
@@ -101,9 +101,11 @@
int main(int argc, char **argv)
{
int i, unmerged;
- int entries = read_cache();
+ int entries;
unsigned char sha1[20];
+ read_cache();
+ entries = get_num_cache_entries();
if (entries <= 0)
die("write-tree: no cache contents to write");
^ permalink raw reply
* [PATCH 17/19] temporarily change add_cache_entry to create an empty cache on demand
From: Brad Roberts @ 2005-04-21 18:38 UTC (permalink / raw)
To: git
tree 6feaeb314fb1bea393250972b109b7d218cf37d7
parent b965055600b8bf4927ea631446cd6cde714aef95
author Brad Roberts <braddr@puremagic.com> 1114087949 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114087949 -0700
[PATCH] temporarily change add_cache_entry to create an empty cache on demand
read-tree.c expects to be able to add entries into an empty cache in the
non-merging mode.
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
read-cache.c | 26 ++++++++++++++++++--------
1 files changed, 18 insertions(+), 8 deletions(-)
Index: read-cache.c
===================================================================
--- b965055600b8bf4927ea631446cd6cde714aef95:1/read-cache.c (mode:100644 sha1:c399f8e497441147afe630ca080558a8c6c79c78)
+++ 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/read-cache.c (mode:100644 sha1:31e293a3686622c9ec180d41aa37d85ce49325e8)
@@ -32,6 +32,18 @@
static struct cache * cache = NULL;
+struct cache * new_cache()
+{
+ return (struct cache*)calloc(1, sizeof(struct cache));
+}
+
+void free_cache()
+{
+ munmap(cache->map.ptr, cache->map.size);
+ free(cache);
+ cache = NULL;
+}
+
int cache_match_stat(struct cache_entry *ce, struct stat *st)
{
unsigned int changed = 0;
@@ -155,6 +167,11 @@
{
int pos;
+ /* temporary, read-tree.c expects the cache to always exist, even
+ * without a read_cache being called */
+ if (!cache)
+ cache = new_cache();
+
pos = cache_name_pos(ce->name, htons(ce->ce_flags));
/* existing match? Just replace it */
@@ -230,7 +247,7 @@
return (errno == ENOENT) ? 0 : error("open failed");
errno = ENOMEM;
- cache = (struct cache*)malloc(sizeof(struct cache));
+ cache = new_cache();
if (!cache)
return error("unable to allocate cache");
@@ -333,10 +350,3 @@
}
return ce_flush(&c, newfd);
}
-
-void free_cache()
-{
- munmap(cache->map.ptr, cache->map.size);
- free(cache);
- cache = NULL;
-}
^ permalink raw reply
* [PATCH 18/19] rename cache_match_stat to ce_match_stat to match other cache_entry related functions/macros
From: Brad Roberts @ 2005-04-21 18:39 UTC (permalink / raw)
To: git
tree f8dd454f774d42526149193970b612a46f3ddd26
parent 058c25fd81e5949354d96f2aad222ae73a6c1dee
author Brad Roberts <braddr@puremagic.com> 1114088345 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114088345 -0700
[PATCH] rename cache_match_stat to ce_match_stat to match other cache_entry related functions/macros
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
cache.h | 3 ++-
check-files.c | 2 +-
checkout-cache.c | 2 +-
diff-cache.c | 2 +-
read-cache.c | 2 +-
show-diff.c | 2 +-
update-cache.c | 2 +-
7 files changed, 8 insertions(+), 7 deletions(-)
Index: cache.h
===================================================================
--- 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/cache.h (mode:100644 sha1:a3018f9e12bfdd1a5273b20fcab5062667c6caec)
+++ 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/cache.h (mode:100644 sha1:c64969602d80a0e9d7137b2716fb808c912b075c)
@@ -52,6 +52,8 @@
#define CE_STAGEMASK (0x3000)
#define CE_STAGESHIFT 12
+extern int ce_match_stat(struct cache_entry *ce, struct stat *st);
+
#define create_ce_flags(len, stage) htons((len) | ((stage) << CE_STAGESHIFT))
#define ce_namelen(ce) (CE_NAMEMASK & ntohs((ce)->ce_flags))
#define ce_size(ce) cache_entry_size(ce_namelen(ce))
@@ -76,7 +78,6 @@
extern int cache_name_pos(const char *name, int namelen);
extern int add_cache_entry(struct cache_entry *ce, int ok_to_add);
extern int remove_file_from_cache(char *path);
-extern int cache_match_stat(struct cache_entry *ce, struct stat *st);
extern int get_num_cache_entries();
extern struct cache_entry * get_cache_entry(int pos);
extern void set_cache_entry(struct cache_entry *ce, int pos);
Index: check-files.c
===================================================================
--- 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/check-files.c (mode:100644 sha1:919e418b5f0f85220445c876a37bf4cf61d26525)
+++ 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/check-files.c (mode:100644 sha1:0973e81fbbc0f9f98031fb249254bd89d8088889)
@@ -31,7 +31,7 @@
if (fstat(fd, &st) < 0)
die("fstat(%s): %s", path, strerror(errno));
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
if (changed)
die("preparing to update file '%s' not uptodate in cache", path);
}
Index: checkout-cache.c
===================================================================
--- 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/checkout-cache.c (mode:100644 sha1:bf9cd0572c883219d37f2788ec5f5553a136df2b)
+++ 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/checkout-cache.c (mode:100644 sha1:27b559d5bcc5831eda441bcd1fd88d687f2567b8)
@@ -100,7 +100,7 @@
struct stat st;
if (!stat(ce->name, &st)) {
- unsigned changed = cache_match_stat(ce, &st);
+ unsigned changed = ce_match_stat(ce, &st);
if (!changed)
return 0;
if (!force) {
Index: diff-cache.c
===================================================================
--- 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/diff-cache.c (mode:100644 sha1:548211944fc00594bfc06b9ab90f0cb476688285)
+++ 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/diff-cache.c (mode:100644 sha1:5ae6d5de5ed5ad34f72267904ff8eb6288855fc5)
@@ -125,7 +125,7 @@
show_file("-", path1, mode1, sha1, base);
return -1;
}
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
close(fd);
if (changed) {
mode2 = st.st_mode;
Index: read-cache.c
===================================================================
--- 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/read-cache.c (mode:100644 sha1:31e293a3686622c9ec180d41aa37d85ce49325e8)
+++ 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/read-cache.c (mode:100644 sha1:8837d27ab683bf07d38aee33c62a90f5a7221588)
@@ -44,7 +44,7 @@
cache = NULL;
}
-int cache_match_stat(struct cache_entry *ce, struct stat *st)
+int ce_match_stat(struct cache_entry *ce, struct stat *st)
{
unsigned int changed = 0;
Index: show-diff.c
===================================================================
--- 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/show-diff.c (mode:100644 sha1:6e04e9182667cbb79afa4c878a31b685fdea3229)
+++ 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/show-diff.c (mode:100644 sha1:4a0902f50b3120b7791a4d4627a9a4f729afdcf7)
@@ -193,7 +193,7 @@
}
continue;
}
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
if (!changed)
continue;
if (!machine_readable)
Index: update-cache.c
===================================================================
--- 058c25fd81e5949354d96f2aad222ae73a6c1dee:1/update-cache.c (mode:100644 sha1:8328975cb726f5e06a413a9f0099bfa2f81d3381)
+++ 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/update-cache.c (mode:100644 sha1:3f251552283667c42797835088a4922ef865fe4a)
@@ -179,7 +179,7 @@
if (stat(ce->name, &st) < 0)
return NULL;
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
if (!changed)
return ce;
^ permalink raw reply
* [PATCH 19/19] the end goal of the last dozen or so commits, there's no longer a global cache variable
From: Brad Roberts @ 2005-04-21 18:39 UTC (permalink / raw)
To: git
tree 38adb888a4c1adfe083f24d4ec51018e0b5a8335
parent 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac
author Brad Roberts <braddr@puremagic.com> 1114093024 -0700
committer Brad Roberts <braddr@gameboy2.puremagic.com> 1114093024 -0700
[PATCH] the end goal of the last dozen or so commits, there's no longer a global cache variable
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
cache.h | 21 +++++++-------
check-files.c | 10 +++---
checkout-cache.c | 20 ++++++-------
diff-cache.c | 20 ++++++-------
merge-cache.c | 29 ++++++++++---------
read-cache.c | 82 ++++++++++++++++++++++++++++---------------------------
read-tree.c | 51 ++++++++++++++++++----------------
show-diff.c | 8 ++---
show-files.c | 27 +++++++++---------
update-cache.c | 35 ++++++++++++-----------
write-tree.c | 20 ++++++-------
11 files changed, 167 insertions(+), 156 deletions(-)
Index: cache.h
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/cache.h (mode:100644 sha1:c64969602d80a0e9d7137b2716fb808c912b075c)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/cache.h (mode:100644 sha1:d8ade9f4b9bd9b6045f97b4df5bef8356c767d46)
@@ -72,16 +72,17 @@
#define alloc_nr(x) (((x)+16)*3/2)
/* Initialize and use the cache information */
-extern int read_cache(void);
-extern int write_cache(int newfd);
-extern void free_cache();
-extern int cache_name_pos(const char *name, int namelen);
-extern int add_cache_entry(struct cache_entry *ce, int ok_to_add);
-extern int remove_file_from_cache(char *path);
-extern int get_num_cache_entries();
-extern struct cache_entry * get_cache_entry(int pos);
-extern void set_cache_entry(struct cache_entry *ce, int pos);
-extern int remove_cache_entry_at(int pos);
+extern struct cache *new_cache(void);
+extern struct cache *read_cache(void);
+extern int write_cache(struct cache *cache, int newfd);
+extern void free_cache(struct cache *cache);
+extern int cache_name_pos(struct cache *cache, const char *name, int namelen);
+extern int add_cache_entry(struct cache *cache, struct cache_entry *ce, int ok_to_add);
+extern int remove_file_from_cache(struct cache *cache, char *path);
+extern int get_num_cache_entries(struct cache *cache);
+extern struct cache_entry * get_cache_entry(struct cache *cache, int pos);
+extern void set_cache_entry(struct cache *cache, struct cache_entry *ce, int pos);
+extern int remove_cache_entry_at(struct cache *cache, int pos);
#define MTIME_CHANGED 0x0001
#define CTIME_CHANGED 0x0002
Index: check-files.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/check-files.c (mode:100644 sha1:0973e81fbbc0f9f98031fb249254bd89d8088889)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/check-files.c (mode:100644 sha1:4de6d39e4997d29f13261c21eeb378f74b3f8a8f)
@@ -8,7 +8,7 @@
*/
#include "cache.h"
-static void check_file(const char *path)
+static void check_file(struct cache *cache, const char *path)
{
int fd = open(path, O_RDONLY);
struct cache_entry *ce;
@@ -23,10 +23,10 @@
}
/* Exists but is not in the cache is not fine */
- pos = cache_name_pos(path, strlen(path));
+ pos = cache_name_pos(cache, path, strlen(path));
if (pos < 0)
die("preparing to update existing file '%s' not in cache", path);
- ce = get_cache_entry(pos);
+ ce = get_cache_entry(cache, pos);
if (fstat(fd, &st) < 0)
die("fstat(%s): %s", path, strerror(errno));
@@ -39,9 +39,9 @@
int main(int argc, char **argv)
{
int i;
+ struct cache *cache = read_cache();
- read_cache();
for (i = 1; i < argc ; i++)
- check_file(argv[i]);
+ check_file(cache, argv[i]);
return 0;
}
Index: checkout-cache.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/checkout-cache.c (mode:100644 sha1:27b559d5bcc5831eda441bcd1fd88d687f2567b8)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/checkout-cache.c (mode:100644 sha1:2e8c61323a72f6052d8c9ef76a4eef05aa5ac0f9)
@@ -120,23 +120,23 @@
return write_entry(ce);
}
-static int checkout_file(const char *name)
+static int checkout_file(struct cache *cache, const char *name)
{
- int pos = cache_name_pos(name, strlen(name));
+ int pos = cache_name_pos(cache, name, strlen(name));
if (pos < 0) {
if (!quiet)
fprintf(stderr, "checkout-cache: %s is not in the cache\n", name);
return -1;
}
- return checkout_entry(get_cache_entry(pos));
+ return checkout_entry(get_cache_entry(cache, pos));
}
-static int checkout_all(void)
+static int checkout_all(struct cache *cache)
{
int i;
- for (i = 0; i < get_num_cache_entries() ; i++) {
- struct cache_entry *ce = get_cache_entry(i);
+ for (i = 0; i < get_num_cache_entries(cache) ; i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (ce_stage(ce))
continue;
if (checkout_entry(ce) < 0)
@@ -149,15 +149,15 @@
{
int i, force_filename = 0;
- if (read_cache() < 0) {
+ struct cache * cache = read_cache();
+ if (!cache)
die("invalid cache");
- }
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!force_filename) {
if (!strcmp(arg, "-a")) {
- checkout_all();
+ checkout_all(cache);
continue;
}
if (!strcmp(arg, "--")) {
@@ -173,7 +173,7 @@
continue;
}
}
- checkout_file(arg);
+ checkout_file(cache, arg);
}
return 0;
}
Index: diff-cache.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/diff-cache.c (mode:100644 sha1:5ae6d5de5ed5ad34f72267904ff8eb6288855fc5)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/diff-cache.c (mode:100644 sha1:1d39ca1f79d841e363a4be57871a5c1282d441e1)
@@ -4,7 +4,7 @@
static int recursive = 0;
static int line_termination = '\n';
-static int diff_cache(void *tree, unsigned long size, int pos, const char *base);
+static int diff_cache(void *tree, unsigned long size, struct cache *cache, int pos, const char *base);
static void update_tree_entry(void **bufp, unsigned long *sizep)
{
@@ -82,10 +82,10 @@
}
static int compare_tree_entry(const char *path1, unsigned int mode1, const unsigned char *sha1,
- int *pos, const char *base)
+ struct cache *cache, int *pos, const char *base)
{
int baselen = strlen(base);
- struct cache_entry *ce = get_cache_entry(*pos);
+ struct cache_entry *ce = get_cache_entry(cache, *pos);
const char *path2 = ce->name + baselen;
unsigned int mode2 = ntohl(ce->ce_mode);
const unsigned char *sha2 = ce->sha1;
@@ -107,7 +107,7 @@
memcpy(newbase + baselen + pathlen1, "/", 2);
if (!tree || strcmp(type, "tree"))
die("unable to read tree object %s", sha1_to_hex(sha1));
- *pos = diff_cache(tree, size, *pos, newbase);
+ *pos = diff_cache(tree, size, cache, *pos, newbase);
free(newbase);
free(tree);
return -1;
@@ -158,7 +158,7 @@
return 0;
}
-static int diff_cache(void *tree, unsigned long size, int pos, const char *base)
+static int diff_cache(void *tree, unsigned long size, struct cache *cache, int pos, const char *base)
{
int baselen = strlen(base);
@@ -172,8 +172,8 @@
* No entries in the cache (with this base)?
* Output the tree contents.
*/
- if ((pos == get_num_cache_entries()) ||
- ce_namelen(ce = get_cache_entry(pos)) < baselen ||
+ if ((pos == get_num_cache_entries(cache)) ||
+ ce_namelen(ce = get_cache_entry(cache, pos)) < baselen ||
memcmp(ce->name, base, baselen)) {
if (!size)
return pos;
@@ -193,7 +193,7 @@
}
sha1 = extract(tree, size, &path, &mode);
- switch (compare_tree_entry(path, mode, sha1, &pos, base)) {
+ switch (compare_tree_entry(path, mode, sha1, cache, &pos, base)) {
case -1:
update_tree_entry(&tree, &size);
continue;
@@ -215,8 +215,8 @@
void *tree;
unsigned long size;
char type[20];
+ struct cache *cache = read_cache();
- read_cache();
while (argc > 2) {
char *arg = argv[1];
argv++;
@@ -257,5 +257,5 @@
if (strcmp(type, "tree"))
die("bad tree object %s (%s)", sha1_to_hex(tree_sha1), type);
- return diff_cache(tree, size, 0, "");
+ return diff_cache(tree, size, cache, 0, "");
}
Index: merge-cache.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/merge-cache.c (mode:100644 sha1:c2f96e7652a2aea9417c3790bfe9ab14ffcdb12f)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/merge-cache.c (mode:100644 sha1:440d4d6e98d1387c5055ba5539b829e7557d9d4a)
@@ -26,11 +26,11 @@
err = 1;
}
-static int merge_entry(int pos, const char *path)
+static int merge_entry(struct cache *cache, int pos, const char *path)
{
int found;
- if (pos >= get_num_cache_entries())
+ if (pos >= get_num_cache_entries(cache))
die("merge-cache: %s not in the cache", path);
arguments[0] = pgm;
arguments[1] = "";
@@ -40,7 +40,7 @@
found = 0;
do {
static char hexbuf[4][60];
- struct cache_entry *ce = get_cache_entry(pos);
+ struct cache_entry *ce = get_cache_entry(cache, pos);
int stage = ce_stage(ce);
if (strcmp(ce->name, path))
@@ -48,44 +48,45 @@
found++;
strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));
arguments[stage] = hexbuf[stage];
- } while (++pos < get_num_cache_entries());
+ } while (++pos < get_num_cache_entries(cache));
if (!found)
die("merge-cache: %s not in the cache", path);
run_program();
return found;
}
-static void merge_file(const char *path)
+static void merge_file(struct cache *cache, const char *path)
{
- int pos = cache_name_pos(path, strlen(path));
+ int pos = cache_name_pos(cache, path, strlen(path));
/*
* If it already exists in the cache as stage0, it's
* already merged and there is nothing to do.
*/
if (pos < 0)
- merge_entry(-pos-1, path);
+ merge_entry(cache, -pos-1, path);
}
-static void merge_all(void)
+static void merge_all(struct cache *cache)
{
int i;
- for (i = 0; i < get_num_cache_entries(); i++) {
- struct cache_entry *ce = get_cache_entry(i);
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (!ce_stage(ce))
continue;
- i += merge_entry(i, ce->name)-1;
+ i += merge_entry(cache, i, ce->name)-1;
}
}
int main(int argc, char **argv)
{
int i, force_file = 0;
+ struct cache *cache;
if (argc < 3)
usage("merge-cache <merge-program> (-a | <filename>*)");
- read_cache();
+ cache = read_cache();
pgm = argv[1];
for (i = 2; i < argc; i++) {
@@ -96,12 +97,12 @@
continue;
}
if (!strcmp(arg, "-a")) {
- merge_all();
+ merge_all(cache);
continue;
}
die("merge-cache: unknown option %s", arg);
}
- merge_file(arg);
+ merge_file(cache, arg);
}
if (err)
die("merge program failed");
Index: read-cache.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/read-cache.c (mode:100644 sha1:8837d27ab683bf07d38aee33c62a90f5a7221588)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/read-cache.c (mode:100644 sha1:7084fcdf771ddc5bfac38b8778a5904d779de3a4)
@@ -30,18 +30,15 @@
unsigned int allocated_entries;
};
-static struct cache * cache = NULL;
-
struct cache * new_cache()
{
return (struct cache*)calloc(1, sizeof(struct cache));
}
-void free_cache()
+void free_cache(struct cache *cache)
{
munmap(cache->map.ptr, cache->map.size);
free(cache);
- cache = NULL;
}
int ce_match_stat(struct cache_entry *ce, struct stat *st)
@@ -100,7 +97,7 @@
return 0;
}
-int cache_name_pos(const char *name, int namelen)
+int cache_name_pos(struct cache *cache, const char *name, int namelen)
{
int first, last;
@@ -122,7 +119,7 @@
}
/* Remove entry, return true if there are more entries to go.. */
-int remove_cache_entry_at(int pos)
+int remove_cache_entry_at(struct cache *cache, int pos)
{
cache->num_entries--;
if (pos >= cache->num_entries)
@@ -131,11 +128,11 @@
return 1;
}
-int remove_file_from_cache(char *path)
+int remove_file_from_cache(struct cache *cache, char *path)
{
- int pos = cache_name_pos(path, strlen(path));
+ int pos = cache_name_pos(cache, path, strlen(path));
if (pos >= 0)
- remove_cache_entry_at(pos);
+ remove_cache_entry_at(cache, pos);
return 0;
}
@@ -145,17 +142,17 @@
return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
}
-int get_num_cache_entries()
+int get_num_cache_entries(struct cache *cache)
{
return cache->num_entries;
}
-struct cache_entry * get_cache_entry(int pos)
+struct cache_entry * get_cache_entry(struct cache *cache, int pos)
{
return cache->entries[pos];
}
-void set_cache_entry(struct cache_entry *ce, int pos)
+void set_cache_entry(struct cache *cache, struct cache_entry *ce, int pos)
{
/* You can NOT just free cache->entries[i] here, since it
* might not be necessarily malloc()ed but can also come
@@ -163,16 +160,11 @@
cache->entries[pos] = ce;
}
-int add_cache_entry(struct cache_entry *ce, int ok_to_add)
+int add_cache_entry(struct cache *cache, struct cache_entry *ce, int ok_to_add)
{
int pos;
- /* temporary, read-tree.c expects the cache to always exist, even
- * without a read_cache being called */
- if (!cache)
- cache = new_cache();
-
- pos = cache_name_pos(ce->name, htons(ce->ce_flags));
+ pos = cache_name_pos(cache, ce->name, htons(ce->ce_flags));
/* existing match? Just replace it */
if (pos >= 0) {
@@ -188,7 +180,7 @@
if (pos < cache->num_entries && ce_stage(ce) == 0) {
while (same_name(cache->entries[pos], ce)) {
ok_to_add = 1;
- if (!remove_cache_entry_at(pos))
+ if (!remove_cache_entry_at(cache, pos))
break;
}
}
@@ -227,29 +219,40 @@
return 0;
}
-int read_cache(void)
+struct cache *read_cache(void)
{
int fd, i;
struct stat st;
unsigned long offset;
+ struct cache *cache;
+
+ cache = new_cache();
+ if (!cache) {
+ errno = ENOMEM;
+ error("unable to allocate cache");
+ return NULL;
+ }
- errno = EBUSY;
- if (cache)
- return error("more than one cachefile");
errno = ENOENT;
sha1_file_directory = getenv(DB_ENVIRONMENT);
if (!sha1_file_directory)
sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
- if (access(sha1_file_directory, X_OK) < 0)
- return error("no access to SHA1 file directory");
+ if (access(sha1_file_directory, X_OK) < 0) {
+ error("no access to SHA1 file directory");
+ free(cache);
+ return NULL;
+ }
fd = open(".git/index", O_RDONLY);
- if (fd < 0)
- return (errno == ENOENT) ? 0 : error("open failed");
-
- errno = ENOMEM;
- cache = new_cache();
- if (!cache)
- return error("unable to allocate cache");
+ if (fd < 0) {
+ /* TODO: Why special case this? If we can't get to the data, what's the point? */
+ if (errno == ENOENT)
+ return cache;
+ else {
+ error("open failed");
+ free(cache);
+ return NULL;
+ }
+ }
cache->map.size = 0; /* avoid gcc warning */
cache->map.ptr = (void *)-1;
@@ -261,16 +264,17 @@
}
close(fd);
if (-1 == (int)(long)cache->map.ptr) {
+ error("mmap failed");
free(cache);
- cache = NULL;
- return error("mmap failed");
+ return NULL;
}
cache->header = cache->map.ptr;
if (verify_hdr(cache->header, cache->map.size) < 0) {
- free_cache();
+ free_cache(cache);
errno = EINVAL;
- return error("verify header failed");
+ error("verify header failed");
+ return NULL;
}
cache->num_entries = ntohl(cache->header->hdr_entries);
@@ -283,7 +287,7 @@
offset = offset + ce_size(ce);
cache->entries[i] = ce;
}
- return cache->num_entries;
+ return cache;
}
#define WRITE_BUFFER_SIZE 8192
@@ -329,7 +333,7 @@
return 0;
}
-int write_cache(int newfd)
+int write_cache(struct cache *cache, int newfd)
{
SHA_CTX c;
struct cache_header hdr;
Index: read-tree.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/read-tree.c (mode:100644 sha1:ad9128f26613a82361475516dd0f2b470f4ce4b3)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/read-tree.c (mode:100644 sha1:a683b7f60e58514d36218a7b2c2ace2d3ec9f984)
@@ -7,7 +7,7 @@
static int stage = 0;
-static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode)
+static int read_one_entry(struct cache *cache, unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode)
{
int len = strlen(pathname);
unsigned int size = cache_entry_size(baselen + len);
@@ -20,10 +20,10 @@
memcpy(ce->name, base, baselen);
memcpy(ce->name + baselen, pathname, len+1);
memcpy(ce->sha1, sha1, 20);
- return add_cache_entry(ce, 1);
+ return add_cache_entry(cache, ce, 1);
}
-static int read_tree(unsigned char *sha1, const char *base, int baselen)
+static int read_tree(struct cache *cache, unsigned char *sha1, const char *base, int baselen)
{
void *buffer, *bufptr;
unsigned long size;
@@ -57,7 +57,7 @@
memcpy(newbase, base, baselen);
memcpy(newbase + baselen, path, pathlen);
newbase[baselen + pathlen] = '/';
- retval = read_tree(sha1, newbase, baselen + pathlen + 1);
+ retval = read_tree(cache, sha1, newbase, baselen + pathlen + 1);
free(newbase);
if (retval) {
free(buffer);
@@ -65,7 +65,7 @@
}
continue;
}
- if (read_one_entry(sha1, base, baselen, path, mode) < 0) {
+ if (read_one_entry(cache, sha1, base, baselen, path, mode) < 0) {
free(buffer);
return -1;
}
@@ -149,16 +149,16 @@
/* rather than doing the 'right' thing of deleting entries as we merge,
* walk dst through the cache, overwriting entries as we go and at the
* end truncate the size of the cache */
-static void trivially_merge_cache()
+static void trivially_merge_cache(struct cache *cache)
{
static struct cache_entry null_entry;
struct cache_entry *old = &null_entry;
- int src = 0, dst = 0, nr = get_num_cache_entries();
+ int src = 0, dst = 0, nr = get_num_cache_entries(cache);
while (src < nr) {
struct cache_entry *ce, *result;
- ce = get_cache_entry(src);
+ ce = get_cache_entry(cache, src);
/* We throw away original cache entries except for the stat information */
if (!ce_stage(ce)) {
@@ -168,8 +168,8 @@
}
if ((src < (nr - 2)) &&
(result = merge_entries(ce,
- get_cache_entry(src + 1),
- get_cache_entry(src + 2))) != NULL) {
+ get_cache_entry(cache, src + 1),
+ get_cache_entry(cache, src + 2))) != NULL) {
/*
* See if we can re-use the old CE directly?
* That way we get the uptodate stat info.
@@ -180,27 +180,27 @@
ce->ce_flags &= ~htons(CE_STAGEMASK);
src += 2;
}
- set_cache_entry(ce, dst);
+ set_cache_entry(cache, ce, dst);
dst++;
src++;
}
/* this could be replaced by a truncate api */
while (nr > dst) {
nr--;
- remove_cache_entry_at(nr);
+ remove_cache_entry_at(cache, nr);
}
}
-static void merge_stat_info()
+static void merge_stat_info(struct cache *cache)
{
static struct cache_entry null_entry;
struct cache_entry *old = &null_entry;
- int src = 0, dst = 0, nr = get_num_cache_entries();
+ int src = 0, dst = 0, nr = get_num_cache_entries(cache);
while (src < nr) {
struct cache_entry *ce;
- ce = get_cache_entry(src);
+ ce = get_cache_entry(cache, src);
/* We throw away original cache entries except for the stat information */
if (!ce_stage(ce)) {
@@ -211,14 +211,14 @@
if (path_matches(ce, old) && same(ce, old))
*ce = *old;
ce->ce_flags &= ~htons(CE_STAGEMASK);
- set_cache_entry(ce, dst);
+ set_cache_entry(cache, ce, dst);
dst++;
src++;
}
/* this could be replaced by a truncate api */
while (nr > dst) {
nr--;
- remove_cache_entry_at(nr);
+ remove_cache_entry_at(cache, nr);
}
}
@@ -226,6 +226,7 @@
{
int i, newfd, merge;
unsigned char sha1[20];
+ struct cache *cache = NULL;
newfd = open(".git/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
if (newfd < 0)
@@ -242,9 +243,9 @@
int i;
if (stage)
usage("-m needs to come first");
- read_cache();
- for (i = 0; i < get_num_cache_entries(); i++) {
- if (ce_stage(get_cache_entry(i)))
+ cache = read_cache();
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ if (ce_stage(get_cache_entry(cache, i)))
usage("you need to resolve your current index first");
}
stage = 1;
@@ -255,23 +256,25 @@
usage("read-tree [-m] <sha1>");
if (stage > 3)
usage("can't merge more than two trees");
- if (read_tree(sha1, "", 0) < 0)
+ if (!cache)
+ cache = new_cache();
+ if (read_tree(cache, sha1, "", 0) < 0)
die("failed to unpack tree object %s", arg);
stage++;
}
if (merge) {
switch (stage) {
case 4: /* Three-way merge */
- trivially_merge_cache();
+ trivially_merge_cache(cache);
break;
case 2: /* Just read a tree, merge with old cache contents */
- merge_stat_info();
+ merge_stat_info(cache);
break;
default:
die("just how do you expect me to merge %d trees?", stage-1);
}
}
- if (write_cache(newfd) ||
+ if (write_cache(cache, newfd) ||
rename(".git/index.lock", ".git/index"))
die("unable to write new index file");
remove_lock = 0;
Index: show-diff.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/show-diff.c (mode:100644 sha1:4a0902f50b3120b7791a4d4627a9a4f729afdcf7)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/show-diff.c (mode:100644 sha1:d61bf6dea8106599c25ac5071743b351f6e000ce)
@@ -129,9 +129,9 @@
int entries;
int matched = 0;
int i;
+ struct cache *cache = read_cache();
- read_cache();
- entries = get_num_cache_entries();
+ entries = get_num_cache_entries(cache);
if (entries < 0) {
perror("read_cache");
exit(1);
@@ -157,7 +157,7 @@
prepare_diff_cmd();
for (i = 0; i < entries; i++) {
struct stat st;
- struct cache_entry *ce = get_cache_entry(i);
+ struct cache_entry *ce = get_cache_entry(cache, i);
int changed;
unsigned long size;
char type[20];
@@ -175,7 +175,7 @@
printf("%s: Unmerged\n",
ce->name);
while (i < entries &&
- !strcmp(ce->name, get_cache_entry(i)->name))
+ !strcmp(ce->name, get_cache_entry(cache, i)->name))
i++;
i--; /* compensate for loop control increments */
continue;
Index: show-files.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/show-files.c (mode:100644 sha1:11fbbccef2df50d528105ceb48b15275f2a5693e)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/show-files.c (mode:100644 sha1:c8dc21d0dd3f5db3f7016323859c58449968d800)
@@ -27,11 +27,11 @@
static int nr_dir;
static int dir_alloc;
-static void add_name(const char *pathname, int len)
+static void add_name(struct cache *cache, const char *pathname, int len)
{
char *name;
- if (cache_name_pos(pathname, len) >= 0)
+ if (cache_name_pos(cache, pathname, len) >= 0)
return;
if (nr_dir == dir_alloc) {
@@ -51,7 +51,7 @@
* Also, we currently ignore all names starting with a dot.
* That likely will not change.
*/
-static void read_directory(const char *path, const char *base, int baselen)
+static void read_directory(struct cache *cache, const char *path, const char *base, int baselen)
{
DIR *dir = opendir(path);
@@ -82,12 +82,12 @@
/* fallthrough */
case DT_DIR:
memcpy(fullname + baselen + len, "/", 2);
- read_directory(fullname, fullname, baselen + len + 1);
+ read_directory(cache, fullname, fullname, baselen + len + 1);
continue;
case DT_REG:
break;
}
- add_name(fullname, baselen + len);
+ add_name(cache, fullname, baselen + len);
}
closedir(dir);
}
@@ -102,13 +102,13 @@
return cache_name_compare(n1, l1, n2, l2);
}
-static void show_files(void)
+static void show_files(struct cache *cache)
{
int i;
/* For cached/deleted files we don't need to even do the readdir */
if (show_others | show_ignored) {
- read_directory(".", "", 0);
+ read_directory(cache, ".", "", 0);
qsort(dir, nr_dir, sizeof(char *), cmp_name);
}
if (show_others) {
@@ -116,8 +116,8 @@
printf("%s%s%c", tag_other, dir[i], line_terminator);
}
if (show_cached | show_stage) {
- for (i = 0; i < get_num_cache_entries(); i++) {
- struct cache_entry *ce = get_cache_entry(i);
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (show_unmerged && !ce_stage(ce))
continue;
if (!show_stage)
@@ -136,8 +136,8 @@
}
}
if (show_deleted) {
- for (i = 0; i < get_num_cache_entries(); i++) {
- struct cache_entry *ce = get_cache_entry(i);
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
struct stat st;
if (!stat(ce->name, &st))
continue;
@@ -152,6 +152,7 @@
int main(int argc, char **argv)
{
int i;
+ struct cache *cache;
for (i = 1; i < argc; i++) {
char *arg = argv[i];
@@ -202,7 +203,7 @@
if (!(show_stage | show_deleted | show_others | show_ignored | show_unmerged))
show_cached = 1;
- read_cache();
- show_files();
+ cache = read_cache();
+ show_files(cache);
return 0;
}
Index: update-cache.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/update-cache.c (mode:100644 sha1:3f251552283667c42797835088a4922ef865fe4a)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/update-cache.c (mode:100644 sha1:565638acd2380023ea69e82316a7ab77d95d8ee7)
@@ -85,7 +85,7 @@
ce->ce_size = htonl(st->st_size);
}
-static int add_file_to_cache(char *path)
+static int add_file_to_cache(struct cache *cache, char *path)
{
int size, namelen;
struct cache_entry *ce;
@@ -96,7 +96,7 @@
if (fd < 0) {
if (errno == ENOENT) {
if (allow_remove)
- return remove_file_from_cache(path);
+ return remove_file_from_cache(cache, path);
}
return -1;
}
@@ -117,7 +117,7 @@
free(ce);
return -1;
}
- if (add_cache_entry(ce, allow_add)) {
+ if (add_cache_entry(cache, ce, allow_add)) {
free(ce);
return -1;
}
@@ -200,17 +200,17 @@
return updated;
}
-static void refresh_cache(void)
+static void refresh_cache(struct cache *cache)
{
int i;
- for (i = 0; i < get_num_cache_entries(); i++) {
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
struct cache_entry *ce, *new;
- ce = get_cache_entry(i);
+ ce = get_cache_entry(cache, i);
if (ce_stage(ce)) {
printf("%s: needs merge\n", ce->name);
- while ((i < get_num_cache_entries()) &&
- ! strcmp(get_cache_entry(i)->name, ce->name))
+ while ((i < get_num_cache_entries(cache)) &&
+ ! strcmp(get_cache_entry(cache, i)->name, ce->name))
i++;
i--;
continue;
@@ -221,7 +221,7 @@
printf("%s: needs update\n", ce->name);
continue;
}
- set_cache_entry(new, i);
+ set_cache_entry(cache, new, i);
}
}
@@ -253,7 +253,7 @@
}
}
-static int add_cacheinfo(char *arg1, char *arg2, char *arg3)
+static int add_cacheinfo(struct cache *cache, char *arg1, char *arg2, char *arg3)
{
int size, len;
unsigned int mode;
@@ -276,7 +276,7 @@
memcpy(ce->name, arg3, len);
ce->ce_flags = htons(len);
ce->ce_mode = create_ce_mode(mode);
- return add_cache_entry(ce, allow_add);
+ return add_cache_entry(cache, ce, allow_add);
}
static int remove_lock = 0;
@@ -291,6 +291,7 @@
{
int i, newfd, entries;
int allow_options = 1;
+ struct cache *cache = NULL;
newfd = open(".git/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
if (newfd < 0)
@@ -299,8 +300,8 @@
atexit(remove_lock_file);
remove_lock = 1;
- read_cache();
- entries = get_num_cache_entries();
+ cache = read_cache();
+ entries = get_num_cache_entries(cache);
if (entries < 0)
die("cache corrupted");
@@ -321,11 +322,11 @@
continue;
}
if (!strcmp(path, "--refresh")) {
- refresh_cache();
+ refresh_cache(cache);
continue;
}
if (!strcmp(path, "--cacheinfo")) {
- if (i+3 >= argc || add_cacheinfo(argv[i+1], argv[i+2], argv[i+3]))
+ if (i+3 >= argc || add_cacheinfo(cache, argv[i+1], argv[i+2], argv[i+3]))
die("update-cache: --cacheinfo <mode> <sha1> <path>");
i += 3;
continue;
@@ -336,10 +337,10 @@
fprintf(stderr, "Ignoring path %s\n", argv[i]);
continue;
}
- if (add_file_to_cache(path))
+ if (add_file_to_cache(cache, path))
die("Unable to add %s to database", path);
}
- if (write_cache(newfd) ||
+ if (write_cache(cache, newfd) ||
rename(".git/index.lock", ".git/index"))
die("Unable to write new cachefile");
Index: write-tree.c
===================================================================
--- 0a556dc01b8e48f684ce6e0c26f8c00b5e39c4ac:1/write-tree.c (mode:100644 sha1:92e707fd4780805da160ce6fa282e75111ea67b9)
+++ 7e396358c12c0129bcb4945e3e35a4fa76890a0c:1/write-tree.c (mode:100644 sha1:ad148b422ffa85d7ecf515e55538c1afa13f17d6)
@@ -29,7 +29,7 @@
#define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
-static int write_tree(int start_pos, const char *base, int baselen, unsigned char *returnsha1)
+static int write_tree(struct cache *cache, int start_pos, const char *base, int baselen, unsigned char *returnsha1)
{
unsigned char subdir_sha1[20];
unsigned long size, offset;
@@ -43,7 +43,7 @@
nr = 0;
do {
- struct cache_entry *ce = get_cache_entry(start_pos + nr);
+ struct cache_entry *ce = get_cache_entry(cache, start_pos + nr);
const char *pathname = ce->name, *filename, *dirname;
int pathlen = ce_namelen(ce), entrylen;
unsigned char *sha1;
@@ -59,7 +59,7 @@
if (dirname) {
int subdir_written;
- subdir_written = write_tree(start_pos + nr, pathname, dirname-pathname+1, subdir_sha1);
+ subdir_written = write_tree(cache, start_pos + nr, pathname, dirname-pathname+1, subdir_sha1);
nr += subdir_written;
/* Now we need to write out the directory entry into this tree.. */
@@ -87,7 +87,7 @@
memcpy(buffer + offset, sha1, 20);
offset += 20;
nr++;
- } while ((start_pos + nr) < get_num_cache_entries());
+ } while ((start_pos + nr) < get_num_cache_entries(cache));
i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
i -= 5;
@@ -101,18 +101,18 @@
int main(int argc, char **argv)
{
int i, unmerged;
- int entries;
unsigned char sha1[20];
+ struct cache *cache = read_cache();
+ int entries;
- read_cache();
- entries = get_num_cache_entries();
- if (entries <= 0)
+ if (!cache)
die("write-tree: no cache contents to write");
+ entries = get_num_cache_entries(cache);
/* Verify that the tree is merged */
unmerged = 0;
for (i = 0; i < entries; i++) {
- struct cache_entry *ce = get_cache_entry(i);
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) {
if (++unmerged > 10) {
fprintf(stderr, "...\n");
@@ -125,7 +125,7 @@
die("write-tree: not able to write tree");
/* Ok, write it out */
- if (write_tree(0, "", 0, sha1) != entries)
+ if (write_tree(cache, 0, "", 0, sha1) != entries)
die("write-tree: internal error");
printf("%s\n", sha1_to_hex(sha1));
return 0;
^ permalink raw reply
* [PATCH 01-19/19] All of the above combined
From: Brad Roberts @ 2005-04-21 18:39 UTC (permalink / raw)
To: git
Make the cache management code behave more like a library. There are no
longer any global variables in read-cache.c. Nothing ever uses more than
one cache yet, but I can see how it might simplify some of the merge code.
Signed-off-by: Brad Roberts <braddr@puremagic.com>
---
cache.h | 36 +++------
check-files.c | 12 +--
checkout-cache.c | 22 +++---
diff-cache.c | 36 ++++-----
merge-cache.c | 29 ++++---
read-cache.c | 200 ++++++++++++++++++++++++++++++++++++-------------------
read-tree.c | 71 +++++++++++--------
show-diff.c | 19 +++--
show-files.c | 27 +++----
update-cache.c | 39 +++++-----
write-tree.c | 24 +++---
11 files changed, 292 insertions(+), 223 deletions(-)
Index: cache.h
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/cache.h (mode:100644 sha1:828d660ab82bb35a1ca632a2ba4620dc483889bd)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/cache.h (mode:100644 sha1:d8ade9f4b9bd9b6045f97b4df5bef8356c767d46)
@@ -17,21 +17,6 @@
#include <zlib.h>
/*
- * Basic data structures for the directory cache
- *
- * NOTE NOTE NOTE! This is all in the native CPU byte format. It's
- * not even trying to be portable. It's trying to be efficient. It's
- * just a cache, after all.
- */
-
-#define CACHE_SIGNATURE 0x44495243 /* "DIRC" */
-struct cache_header {
- unsigned int hdr_signature;
- unsigned int hdr_version;
- unsigned int hdr_entries;
-};
-
-/*
* The "cache_time" is just the low 32 bits of the
* time. It doesn't matter if it overflows - we only
* check it for equality in the 32 bits we save.
@@ -67,6 +52,8 @@
#define CE_STAGEMASK (0x3000)
#define CE_STAGESHIFT 12
+extern int ce_match_stat(struct cache_entry *ce, struct stat *st);
+
#define create_ce_flags(len, stage) htons((len) | ((stage) << CE_STAGESHIFT))
#define ce_namelen(ce) (CE_NAMEMASK & ntohs((ce)->ce_flags))
#define ce_size(ce) cache_entry_size(ce_namelen(ce))
@@ -78,8 +65,6 @@
#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
const char *sha1_file_directory;
-struct cache_entry **active_cache;
-unsigned int active_nr, active_alloc;
#define DB_ENVIRONMENT "SHA1_FILE_DIRECTORY"
#define DEFAULT_DB_ENVIRONMENT ".git/objects"
@@ -87,12 +72,17 @@
#define alloc_nr(x) (((x)+16)*3/2)
/* Initialize and use the cache information */
-extern int read_cache(void);
-extern int write_cache(int newfd, struct cache_entry **cache, int entries);
-extern int cache_name_pos(const char *name, int namelen);
-extern int add_cache_entry(struct cache_entry *ce, int ok_to_add);
-extern int remove_file_from_cache(char *path);
-extern int cache_match_stat(struct cache_entry *ce, struct stat *st);
+extern struct cache *new_cache(void);
+extern struct cache *read_cache(void);
+extern int write_cache(struct cache *cache, int newfd);
+extern void free_cache(struct cache *cache);
+extern int cache_name_pos(struct cache *cache, const char *name, int namelen);
+extern int add_cache_entry(struct cache *cache, struct cache_entry *ce, int ok_to_add);
+extern int remove_file_from_cache(struct cache *cache, char *path);
+extern int get_num_cache_entries(struct cache *cache);
+extern struct cache_entry * get_cache_entry(struct cache *cache, int pos);
+extern void set_cache_entry(struct cache *cache, struct cache_entry *ce, int pos);
+extern int remove_cache_entry_at(struct cache *cache, int pos);
#define MTIME_CHANGED 0x0001
#define CTIME_CHANGED 0x0002
Index: check-files.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/check-files.c (mode:100644 sha1:7d16691aa9d51b5b4670d5837b3527ee7c7da79c)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/check-files.c (mode:100644 sha1:4de6d39e4997d29f13261c21eeb378f74b3f8a8f)
@@ -8,7 +8,7 @@
*/
#include "cache.h"
-static void check_file(const char *path)
+static void check_file(struct cache *cache, const char *path)
{
int fd = open(path, O_RDONLY);
struct cache_entry *ce;
@@ -23,15 +23,15 @@
}
/* Exists but is not in the cache is not fine */
- pos = cache_name_pos(path, strlen(path));
+ pos = cache_name_pos(cache, path, strlen(path));
if (pos < 0)
die("preparing to update existing file '%s' not in cache", path);
- ce = active_cache[pos];
+ ce = get_cache_entry(cache, pos);
if (fstat(fd, &st) < 0)
die("fstat(%s): %s", path, strerror(errno));
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
if (changed)
die("preparing to update file '%s' not uptodate in cache", path);
}
@@ -39,9 +39,9 @@
int main(int argc, char **argv)
{
int i;
+ struct cache *cache = read_cache();
- read_cache();
for (i = 1; i < argc ; i++)
- check_file(argv[i]);
+ check_file(cache, argv[i]);
return 0;
}
Index: checkout-cache.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/checkout-cache.c (mode:100644 sha1:8bf86016b5d5fd88a52ce694fc59bb9ecb550d22)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/checkout-cache.c (mode:100644 sha1:2e8c61323a72f6052d8c9ef76a4eef05aa5ac0f9)
@@ -100,7 +100,7 @@
struct stat st;
if (!stat(ce->name, &st)) {
- unsigned changed = cache_match_stat(ce, &st);
+ unsigned changed = ce_match_stat(ce, &st);
if (!changed)
return 0;
if (!force) {
@@ -120,23 +120,23 @@
return write_entry(ce);
}
-static int checkout_file(const char *name)
+static int checkout_file(struct cache *cache, const char *name)
{
- int pos = cache_name_pos(name, strlen(name));
+ int pos = cache_name_pos(cache, name, strlen(name));
if (pos < 0) {
if (!quiet)
fprintf(stderr, "checkout-cache: %s is not in the cache\n", name);
return -1;
}
- return checkout_entry(active_cache[pos]);
+ return checkout_entry(get_cache_entry(cache, pos));
}
-static int checkout_all(void)
+static int checkout_all(struct cache *cache)
{
int i;
- for (i = 0; i < active_nr ; i++) {
- struct cache_entry *ce = active_cache[i];
+ for (i = 0; i < get_num_cache_entries(cache) ; i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (ce_stage(ce))
continue;
if (checkout_entry(ce) < 0)
@@ -149,15 +149,15 @@
{
int i, force_filename = 0;
- if (read_cache() < 0) {
+ struct cache * cache = read_cache();
+ if (!cache)
die("invalid cache");
- }
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!force_filename) {
if (!strcmp(arg, "-a")) {
- checkout_all();
+ checkout_all(cache);
continue;
}
if (!strcmp(arg, "--")) {
@@ -173,7 +173,7 @@
continue;
}
}
- checkout_file(arg);
+ checkout_file(cache, arg);
}
return 0;
}
Index: diff-cache.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/diff-cache.c (mode:100644 sha1:fcbc4900d32f4ca24f67bb8f0fe344c6c5642ac9)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/diff-cache.c (mode:100644 sha1:1d39ca1f79d841e363a4be57871a5c1282d441e1)
@@ -4,7 +4,7 @@
static int recursive = 0;
static int line_termination = '\n';
-static int diff_cache(void *tree, unsigned long size, struct cache_entry **ac, int entries, const char *base);
+static int diff_cache(void *tree, unsigned long size, struct cache *cache, int pos, const char *base);
static void update_tree_entry(void **bufp, unsigned long *sizep)
{
@@ -82,10 +82,10 @@
}
static int compare_tree_entry(const char *path1, unsigned int mode1, const unsigned char *sha1,
- struct cache_entry **ac, int *entries, const char *base)
+ struct cache *cache, int *pos, const char *base)
{
int baselen = strlen(base);
- struct cache_entry *ce = *ac;
+ struct cache_entry *ce = get_cache_entry(cache, *pos);
const char *path2 = ce->name + baselen;
unsigned int mode2 = ntohl(ce->ce_mode);
const unsigned char *sha2 = ce->sha1;
@@ -107,7 +107,7 @@
memcpy(newbase + baselen + pathlen1, "/", 2);
if (!tree || strcmp(type, "tree"))
die("unable to read tree object %s", sha1_to_hex(sha1));
- *entries = diff_cache(tree, size, ac, *entries, newbase);
+ *pos = diff_cache(tree, size, cache, *pos, newbase);
free(newbase);
free(tree);
return -1;
@@ -125,7 +125,7 @@
show_file("-", path1, mode1, sha1, base);
return -1;
}
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
close(fd);
if (changed) {
mode2 = st.st_mode;
@@ -158,7 +158,7 @@
return 0;
}
-static int diff_cache(void *tree, unsigned long size, struct cache_entry **ac, int entries, const char *base)
+static int diff_cache(void *tree, unsigned long size, struct cache *cache, int pos, const char *base)
{
int baselen = strlen(base);
@@ -167,15 +167,16 @@
unsigned int mode;
const char *path;
const unsigned char *sha1;
- int left;
/*
* No entries in the cache (with this base)?
* Output the tree contents.
*/
- if (!entries || ce_namelen(ce = *ac) < baselen || memcmp(ce->name, base, baselen)) {
+ if ((pos == get_num_cache_entries(cache)) ||
+ ce_namelen(ce = get_cache_entry(cache, pos)) < baselen ||
+ memcmp(ce->name, base, baselen)) {
if (!size)
- return entries;
+ return pos;
sha1 = extract(tree, size, &path, &mode);
show_file("-", path, mode, sha1, base);
update_tree_entry(&tree, &size);
@@ -187,27 +188,20 @@
*/
if (!size) {
show_file("+", ce->name, ntohl(ce->ce_mode), ce->sha1, "");
- ac++;
- entries--;
+ pos++;
continue;
}
sha1 = extract(tree, size, &path, &mode);
- left = entries;
- switch (compare_tree_entry(path, mode, sha1, ac, &left, base)) {
+ switch (compare_tree_entry(path, mode, sha1, cache, &pos, base)) {
case -1:
update_tree_entry(&tree, &size);
- if (left < entries) {
- ac += (entries - left);
- entries = left;
- }
continue;
case 0:
update_tree_entry(&tree, &size);
/* Fallthrough */
case 1:
- ac++;
- entries--;
+ pos++;
continue;
}
die("diff-cache: internal error");
@@ -221,8 +215,8 @@
void *tree;
unsigned long size;
char type[20];
+ struct cache *cache = read_cache();
- read_cache();
while (argc > 2) {
char *arg = argv[1];
argv++;
@@ -263,5 +257,5 @@
if (strcmp(type, "tree"))
die("bad tree object %s (%s)", sha1_to_hex(tree_sha1), type);
- return diff_cache(tree, size, active_cache, active_nr, "");
+ return diff_cache(tree, size, cache, 0, "");
}
Index: merge-cache.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/merge-cache.c (mode:100644 sha1:35a0d588178aa5371399458b1a15519cffd645b8)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/merge-cache.c (mode:100644 sha1:440d4d6e98d1387c5055ba5539b829e7557d9d4a)
@@ -26,11 +26,11 @@
err = 1;
}
-static int merge_entry(int pos, const char *path)
+static int merge_entry(struct cache *cache, int pos, const char *path)
{
int found;
- if (pos >= active_nr)
+ if (pos >= get_num_cache_entries(cache))
die("merge-cache: %s not in the cache", path);
arguments[0] = pgm;
arguments[1] = "";
@@ -40,7 +40,7 @@
found = 0;
do {
static char hexbuf[4][60];
- struct cache_entry *ce = active_cache[pos];
+ struct cache_entry *ce = get_cache_entry(cache, pos);
int stage = ce_stage(ce);
if (strcmp(ce->name, path))
@@ -48,44 +48,45 @@
found++;
strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));
arguments[stage] = hexbuf[stage];
- } while (++pos < active_nr);
+ } while (++pos < get_num_cache_entries(cache));
if (!found)
die("merge-cache: %s not in the cache", path);
run_program();
return found;
}
-static void merge_file(const char *path)
+static void merge_file(struct cache *cache, const char *path)
{
- int pos = cache_name_pos(path, strlen(path));
+ int pos = cache_name_pos(cache, path, strlen(path));
/*
* If it already exists in the cache as stage0, it's
* already merged and there is nothing to do.
*/
if (pos < 0)
- merge_entry(-pos-1, path);
+ merge_entry(cache, -pos-1, path);
}
-static void merge_all(void)
+static void merge_all(struct cache *cache)
{
int i;
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (!ce_stage(ce))
continue;
- i += merge_entry(i, ce->name)-1;
+ i += merge_entry(cache, i, ce->name)-1;
}
}
int main(int argc, char **argv)
{
int i, force_file = 0;
+ struct cache *cache;
if (argc < 3)
usage("merge-cache <merge-program> (-a | <filename>*)");
- read_cache();
+ cache = read_cache();
pgm = argv[1];
for (i = 2; i < argc; i++) {
@@ -96,12 +97,12 @@
continue;
}
if (!strcmp(arg, "-a")) {
- merge_all();
+ merge_all(cache);
continue;
}
die("merge-cache: unknown option %s", arg);
}
- merge_file(arg);
+ merge_file(cache, arg);
}
if (err)
die("merge program failed");
Index: read-cache.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/read-cache.c (mode:100644 sha1:2f6a4aa18d48865db80459a3459ac4384b0b16c8)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/read-cache.c (mode:100644 sha1:7084fcdf771ddc5bfac38b8778a5904d779de3a4)
@@ -6,10 +6,42 @@
#include <stdarg.h>
#include "cache.h"
-struct cache_entry **active_cache = NULL;
-unsigned int active_nr = 0, active_alloc = 0;
+/*
+ * Basic data structures for the directory cache
+ */
-int cache_match_stat(struct cache_entry *ce, struct stat *st)
+#define CACHE_SIGNATURE 0x44495243 /* "DIRC" */
+struct cache_header {
+ unsigned int hdr_signature;
+ unsigned int hdr_version;
+ unsigned int hdr_entries;
+};
+
+struct mmap_holder {
+ void * ptr;
+ size_t size;
+};
+
+struct cache {
+ struct mmap_holder map;
+ struct cache_header *header;
+ struct cache_entry **entries;
+ unsigned int num_entries;
+ unsigned int allocated_entries;
+};
+
+struct cache * new_cache()
+{
+ return (struct cache*)calloc(1, sizeof(struct cache));
+}
+
+void free_cache(struct cache *cache)
+{
+ munmap(cache->map.ptr, cache->map.size);
+ free(cache);
+}
+
+int ce_match_stat(struct cache_entry *ce, struct stat *st)
{
unsigned int changed = 0;
@@ -65,15 +97,15 @@
return 0;
}
-int cache_name_pos(const char *name, int namelen)
+int cache_name_pos(struct cache *cache, const char *name, int namelen)
{
int first, last;
first = 0;
- last = active_nr;
+ last = cache->num_entries;
while (last > first) {
int next = (last + first) >> 1;
- struct cache_entry *ce = active_cache[next];
+ struct cache_entry *ce = cache->entries[next];
int cmp = cache_name_compare(name, namelen, ce->name, htons(ce->ce_flags));
if (!cmp)
return next;
@@ -87,20 +119,20 @@
}
/* Remove entry, return true if there are more entries to go.. */
-static int remove_entry_at(int pos)
+int remove_cache_entry_at(struct cache *cache, int pos)
{
- active_nr--;
- if (pos >= active_nr)
+ cache->num_entries--;
+ if (pos >= cache->num_entries)
return 0;
- memmove(active_cache + pos, active_cache + pos + 1, (active_nr - pos) * sizeof(struct cache_entry *));
+ memmove(cache->entries + pos, cache->entries + pos + 1, (cache->num_entries - pos) * sizeof(struct cache_entry *));
return 1;
}
-int remove_file_from_cache(char *path)
+int remove_file_from_cache(struct cache *cache, char *path)
{
- int pos = cache_name_pos(path, strlen(path));
+ int pos = cache_name_pos(cache, path, strlen(path));
if (pos >= 0)
- remove_entry_at(pos);
+ remove_cache_entry_at(cache, pos);
return 0;
}
@@ -110,15 +142,33 @@
return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
}
-int add_cache_entry(struct cache_entry *ce, int ok_to_add)
+int get_num_cache_entries(struct cache *cache)
+{
+ return cache->num_entries;
+}
+
+struct cache_entry * get_cache_entry(struct cache *cache, int pos)
+{
+ return cache->entries[pos];
+}
+
+void set_cache_entry(struct cache *cache, struct cache_entry *ce, int pos)
+{
+ /* You can NOT just free cache->entries[i] here, since it
+ * might not be necessarily malloc()ed but can also come
+ * from mmap(). */
+ cache->entries[pos] = ce;
+}
+
+int add_cache_entry(struct cache *cache, struct cache_entry *ce, int ok_to_add)
{
int pos;
- pos = cache_name_pos(ce->name, htons(ce->ce_flags));
+ pos = cache_name_pos(cache, ce->name, htons(ce->ce_flags));
/* existing match? Just replace it */
if (pos >= 0) {
- active_cache[pos] = ce;
+ cache->entries[pos] = ce;
return 0;
}
pos = -pos-1;
@@ -127,10 +177,10 @@
* Inserting a merged entry ("stage 0") into the index
* will always replace all non-merged entries..
*/
- if (pos < active_nr && ce_stage(ce) == 0) {
- while (same_name(active_cache[pos], ce)) {
+ if (pos < cache->num_entries && ce_stage(ce) == 0) {
+ while (same_name(cache->entries[pos], ce)) {
ok_to_add = 1;
- if (!remove_entry_at(pos))
+ if (!remove_cache_entry_at(cache, pos))
break;
}
}
@@ -139,16 +189,16 @@
return -1;
/* Make sure the array is big enough .. */
- if (active_nr == active_alloc) {
- active_alloc = alloc_nr(active_alloc);
- active_cache = realloc(active_cache, active_alloc * sizeof(struct cache_entry *));
+ if (cache->num_entries == cache->allocated_entries) {
+ cache->allocated_entries = alloc_nr(cache->allocated_entries);
+ cache->entries = realloc(cache->entries, cache->allocated_entries * sizeof(struct cache_entry *));
}
/* Add it in.. */
- active_nr++;
- if (active_nr > pos)
- memmove(active_cache + pos + 1, active_cache + pos, (active_nr - pos - 1) * sizeof(ce));
- active_cache[pos] = ce;
+ cache->num_entries++;
+ if (cache->num_entries > pos)
+ memmove(cache->entries + pos + 1, cache->entries + pos, (cache->num_entries - pos - 1) * sizeof(ce));
+ cache->entries[pos] = ce;
return 0;
}
@@ -169,59 +219,75 @@
return 0;
}
-int read_cache(void)
+struct cache *read_cache(void)
{
int fd, i;
struct stat st;
- unsigned long size, offset;
- void *map;
- struct cache_header *hdr;
-
- errno = EBUSY;
- if (active_cache)
- return error("more than one cachefile");
+ unsigned long offset;
+ struct cache *cache;
+
+ cache = new_cache();
+ if (!cache) {
+ errno = ENOMEM;
+ error("unable to allocate cache");
+ return NULL;
+ }
+
errno = ENOENT;
sha1_file_directory = getenv(DB_ENVIRONMENT);
if (!sha1_file_directory)
sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
- if (access(sha1_file_directory, X_OK) < 0)
- return error("no access to SHA1 file directory");
+ if (access(sha1_file_directory, X_OK) < 0) {
+ error("no access to SHA1 file directory");
+ free(cache);
+ return NULL;
+ }
fd = open(".git/index", O_RDONLY);
- if (fd < 0)
- return (errno == ENOENT) ? 0 : error("open failed");
+ if (fd < 0) {
+ /* TODO: Why special case this? If we can't get to the data, what's the point? */
+ if (errno == ENOENT)
+ return cache;
+ else {
+ error("open failed");
+ free(cache);
+ return NULL;
+ }
+ }
- size = 0; /* avoid gcc warning */
- map = (void *)-1;
+ cache->map.size = 0; /* avoid gcc warning */
+ cache->map.ptr = (void *)-1;
if (!fstat(fd, &st)) {
- size = st.st_size;
+ cache->map.size = st.st_size;
errno = EINVAL;
- if (size >= sizeof(struct cache_header) + 20)
- map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (cache->map.size >= sizeof(struct cache_header) + 20)
+ cache->map.ptr = mmap(NULL, cache->map.size, PROT_READ, MAP_PRIVATE, fd, 0);
}
close(fd);
- if (-1 == (int)(long)map)
- return error("mmap failed");
+ if (-1 == (int)(long)cache->map.ptr) {
+ error("mmap failed");
+ free(cache);
+ return NULL;
+ }
- hdr = map;
- if (verify_hdr(hdr, size) < 0)
- goto unmap;
-
- active_nr = ntohl(hdr->hdr_entries);
- active_alloc = alloc_nr(active_nr);
- active_cache = calloc(active_alloc, sizeof(struct cache_entry *));
-
- offset = sizeof(*hdr);
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = map + offset;
- offset = offset + ce_size(ce);
- active_cache[i] = ce;
+ cache->header = cache->map.ptr;
+ if (verify_hdr(cache->header, cache->map.size) < 0) {
+ free_cache(cache);
+ errno = EINVAL;
+ error("verify header failed");
+ return NULL;
}
- return active_nr;
-unmap:
- munmap(map, size);
- errno = EINVAL;
- return error("verify header failed");
+ cache->num_entries = ntohl(cache->header->hdr_entries);
+ cache->allocated_entries = alloc_nr(cache->num_entries);
+ cache->entries = calloc(cache->allocated_entries, sizeof(struct cache_entry *));
+
+ offset = sizeof(*cache->header);
+ for (i = 0; i < cache->num_entries; i++) {
+ struct cache_entry *ce = cache->map.ptr + offset;
+ offset = offset + ce_size(ce);
+ cache->entries[i] = ce;
+ }
+ return cache;
}
#define WRITE_BUFFER_SIZE 8192
@@ -267,7 +333,7 @@
return 0;
}
-int write_cache(int newfd, struct cache_entry **cache, int entries)
+int write_cache(struct cache *cache, int newfd)
{
SHA_CTX c;
struct cache_header hdr;
@@ -275,14 +341,14 @@
hdr.hdr_signature = htonl(CACHE_SIGNATURE);
hdr.hdr_version = htonl(2);
- hdr.hdr_entries = htonl(entries);
+ hdr.hdr_entries = htonl(cache->num_entries);
SHA1_Init(&c);
if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
return -1;
- for (i = 0; i < entries; i++) {
- struct cache_entry *ce = cache[i];
+ for (i = 0; i < cache->num_entries; i++) {
+ struct cache_entry *ce = cache->entries[i];
if (ce_write(&c, newfd, ce, ce_size(ce)) < 0)
return -1;
}
Index: read-tree.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/read-tree.c (mode:100644 sha1:620f3f74eb56366fca8be4d28d7b04875c0fa90c)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/read-tree.c (mode:100644 sha1:a683b7f60e58514d36218a7b2c2ace2d3ec9f984)
@@ -7,7 +7,7 @@
static int stage = 0;
-static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode)
+static int read_one_entry(struct cache *cache, unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode)
{
int len = strlen(pathname);
unsigned int size = cache_entry_size(baselen + len);
@@ -20,10 +20,10 @@
memcpy(ce->name, base, baselen);
memcpy(ce->name + baselen, pathname, len+1);
memcpy(ce->sha1, sha1, 20);
- return add_cache_entry(ce, 1);
+ return add_cache_entry(cache, ce, 1);
}
-static int read_tree(unsigned char *sha1, const char *base, int baselen)
+static int read_tree(struct cache *cache, unsigned char *sha1, const char *base, int baselen)
{
void *buffer, *bufptr;
unsigned long size;
@@ -57,7 +57,7 @@
memcpy(newbase, base, baselen);
memcpy(newbase + baselen, path, pathlen);
newbase[baselen + pathlen] = '/';
- retval = read_tree(sha1, newbase, baselen + pathlen + 1);
+ retval = read_tree(cache, sha1, newbase, baselen + pathlen + 1);
free(newbase);
if (retval) {
free(buffer);
@@ -65,7 +65,7 @@
}
continue;
}
- if (read_one_entry(sha1, base, baselen, path, mode) < 0) {
+ if (read_one_entry(cache, sha1, base, baselen, path, mode) < 0) {
free(buffer);
return -1;
}
@@ -146,26 +146,30 @@
return NULL;
}
-static void trivially_merge_cache(struct cache_entry **src, int nr)
+/* rather than doing the 'right' thing of deleting entries as we merge,
+ * walk dst through the cache, overwriting entries as we go and at the
+ * end truncate the size of the cache */
+static void trivially_merge_cache(struct cache *cache)
{
static struct cache_entry null_entry;
- struct cache_entry **dst = src;
struct cache_entry *old = &null_entry;
+ int src = 0, dst = 0, nr = get_num_cache_entries(cache);
- while (nr) {
+ while (src < nr) {
struct cache_entry *ce, *result;
- ce = src[0];
+ ce = get_cache_entry(cache, src);
/* We throw away original cache entries except for the stat information */
if (!ce_stage(ce)) {
old = ce;
src++;
- nr--;
- active_nr--;
continue;
}
- if (nr > 2 && (result = merge_entries(ce, src[1], src[2])) != NULL) {
+ if ((src < (nr - 2)) &&
+ (result = merge_entries(ce,
+ get_cache_entry(cache, src + 1),
+ get_cache_entry(cache, src + 2))) != NULL) {
/*
* See if we can re-use the old CE directly?
* That way we get the uptodate stat info.
@@ -175,40 +179,46 @@
ce = result;
ce->ce_flags &= ~htons(CE_STAGEMASK);
src += 2;
- nr -= 2;
- active_nr -= 2;
}
- *dst++ = ce;
+ set_cache_entry(cache, ce, dst);
+ dst++;
src++;
+ }
+ /* this could be replaced by a truncate api */
+ while (nr > dst) {
nr--;
+ remove_cache_entry_at(cache, nr);
}
}
-static void merge_stat_info(struct cache_entry **src, int nr)
+static void merge_stat_info(struct cache *cache)
{
static struct cache_entry null_entry;
- struct cache_entry **dst = src;
struct cache_entry *old = &null_entry;
+ int src = 0, dst = 0, nr = get_num_cache_entries(cache);
- while (nr) {
+ while (src < nr) {
struct cache_entry *ce;
- ce = src[0];
+ ce = get_cache_entry(cache, src);
/* We throw away original cache entries except for the stat information */
if (!ce_stage(ce)) {
old = ce;
src++;
- nr--;
- active_nr--;
continue;
}
if (path_matches(ce, old) && same(ce, old))
*ce = *old;
ce->ce_flags &= ~htons(CE_STAGEMASK);
- *dst++ = ce;
+ set_cache_entry(cache, ce, dst);
+ dst++;
src++;
+ }
+ /* this could be replaced by a truncate api */
+ while (nr > dst) {
nr--;
+ remove_cache_entry_at(cache, nr);
}
}
@@ -216,6 +226,7 @@
{
int i, newfd, merge;
unsigned char sha1[20];
+ struct cache *cache = NULL;
newfd = open(".git/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
if (newfd < 0)
@@ -232,9 +243,9 @@
int i;
if (stage)
usage("-m needs to come first");
- read_cache();
- for (i = 0; i < active_nr; i++) {
- if (ce_stage(active_cache[i]))
+ cache = read_cache();
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ if (ce_stage(get_cache_entry(cache, i)))
usage("you need to resolve your current index first");
}
stage = 1;
@@ -245,23 +256,25 @@
usage("read-tree [-m] <sha1>");
if (stage > 3)
usage("can't merge more than two trees");
- if (read_tree(sha1, "", 0) < 0)
+ if (!cache)
+ cache = new_cache();
+ if (read_tree(cache, sha1, "", 0) < 0)
die("failed to unpack tree object %s", arg);
stage++;
}
if (merge) {
switch (stage) {
case 4: /* Three-way merge */
- trivially_merge_cache(active_cache, active_nr);
+ trivially_merge_cache(cache);
break;
case 2: /* Just read a tree, merge with old cache contents */
- merge_stat_info(active_cache, active_nr);
+ merge_stat_info(cache);
break;
default:
die("just how do you expect me to merge %d trees?", stage-1);
}
}
- if (write_cache(newfd, active_cache, active_nr) ||
+ if (write_cache(cache, newfd) ||
rename(".git/index.lock", ".git/index"))
die("unable to write new index file");
remove_lock = 0;
Index: show-diff.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/show-diff.c (mode:100644 sha1:da364e26e28823f951a6be1b686a458575f28ea1)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/show-diff.c (mode:100644 sha1:d61bf6dea8106599c25ac5071743b351f6e000ce)
@@ -126,9 +126,16 @@
int silent_on_nonexisting_files = 0;
int machine_readable = 0;
int reverse = 0;
- int entries = read_cache();
+ int entries;
int matched = 0;
int i;
+ struct cache *cache = read_cache();
+
+ entries = get_num_cache_entries(cache);
+ if (entries < 0) {
+ perror("read_cache");
+ exit(1);
+ }
while (1 < argc && argv[1][0] == '-') {
if (!strcmp(argv[1], "-R"))
@@ -147,14 +154,10 @@
/* At this point, if argc == 1, then we are doing everything.
* Otherwise argv[1] .. argv[argc-1] have the explicit paths.
*/
- if (entries < 0) {
- perror("read_cache");
- exit(1);
- }
prepare_diff_cmd();
for (i = 0; i < entries; i++) {
struct stat st;
- struct cache_entry *ce = active_cache[i];
+ struct cache_entry *ce = get_cache_entry(cache, i);
int changed;
unsigned long size;
char type[20];
@@ -172,7 +175,7 @@
printf("%s: Unmerged\n",
ce->name);
while (i < entries &&
- !strcmp(ce->name, active_cache[i]->name))
+ !strcmp(ce->name, get_cache_entry(cache, i)->name))
i++;
i--; /* compensate for loop control increments */
continue;
@@ -190,7 +193,7 @@
}
continue;
}
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
if (!changed)
continue;
if (!machine_readable)
Index: show-files.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/show-files.c (mode:100644 sha1:0b49ca051de413e7182445dd8fb9144125716974)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/show-files.c (mode:100644 sha1:c8dc21d0dd3f5db3f7016323859c58449968d800)
@@ -27,11 +27,11 @@
static int nr_dir;
static int dir_alloc;
-static void add_name(const char *pathname, int len)
+static void add_name(struct cache *cache, const char *pathname, int len)
{
char *name;
- if (cache_name_pos(pathname, len) >= 0)
+ if (cache_name_pos(cache, pathname, len) >= 0)
return;
if (nr_dir == dir_alloc) {
@@ -51,7 +51,7 @@
* Also, we currently ignore all names starting with a dot.
* That likely will not change.
*/
-static void read_directory(const char *path, const char *base, int baselen)
+static void read_directory(struct cache *cache, const char *path, const char *base, int baselen)
{
DIR *dir = opendir(path);
@@ -82,12 +82,12 @@
/* fallthrough */
case DT_DIR:
memcpy(fullname + baselen + len, "/", 2);
- read_directory(fullname, fullname, baselen + len + 1);
+ read_directory(cache, fullname, fullname, baselen + len + 1);
continue;
case DT_REG:
break;
}
- add_name(fullname, baselen + len);
+ add_name(cache, fullname, baselen + len);
}
closedir(dir);
}
@@ -102,13 +102,13 @@
return cache_name_compare(n1, l1, n2, l2);
}
-static void show_files(void)
+static void show_files(struct cache *cache)
{
int i;
/* For cached/deleted files we don't need to even do the readdir */
if (show_others | show_ignored) {
- read_directory(".", "", 0);
+ read_directory(cache, ".", "", 0);
qsort(dir, nr_dir, sizeof(char *), cmp_name);
}
if (show_others) {
@@ -116,8 +116,8 @@
printf("%s%s%c", tag_other, dir[i], line_terminator);
}
if (show_cached | show_stage) {
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (show_unmerged && !ce_stage(ce))
continue;
if (!show_stage)
@@ -136,8 +136,8 @@
}
}
if (show_deleted) {
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
+ struct cache_entry *ce = get_cache_entry(cache, i);
struct stat st;
if (!stat(ce->name, &st))
continue;
@@ -152,6 +152,7 @@
int main(int argc, char **argv)
{
int i;
+ struct cache *cache;
for (i = 1; i < argc; i++) {
char *arg = argv[i];
@@ -202,7 +203,7 @@
if (!(show_stage | show_deleted | show_others | show_ignored | show_unmerged))
show_cached = 1;
- read_cache();
- show_files();
+ cache = read_cache();
+ show_files(cache);
return 0;
}
Index: update-cache.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/update-cache.c (mode:100644 sha1:a09883541c745c76413c62109a80f40df4b7a7fb)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/update-cache.c (mode:100644 sha1:565638acd2380023ea69e82316a7ab77d95d8ee7)
@@ -85,7 +85,7 @@
ce->ce_size = htonl(st->st_size);
}
-static int add_file_to_cache(char *path)
+static int add_file_to_cache(struct cache *cache, char *path)
{
int size, namelen;
struct cache_entry *ce;
@@ -96,7 +96,7 @@
if (fd < 0) {
if (errno == ENOENT) {
if (allow_remove)
- return remove_file_from_cache(path);
+ return remove_file_from_cache(cache, path);
}
return -1;
}
@@ -117,7 +117,7 @@
free(ce);
return -1;
}
- if (add_cache_entry(ce, allow_add)) {
+ if (add_cache_entry(cache, ce, allow_add)) {
free(ce);
return -1;
}
@@ -179,7 +179,7 @@
if (stat(ce->name, &st) < 0)
return NULL;
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
if (!changed)
return ce;
@@ -200,17 +200,17 @@
return updated;
}
-static void refresh_cache(void)
+static void refresh_cache(struct cache *cache)
{
int i;
- for (i = 0; i < active_nr; i++) {
+ for (i = 0; i < get_num_cache_entries(cache); i++) {
struct cache_entry *ce, *new;
- ce = active_cache[i];
+ ce = get_cache_entry(cache, i);
if (ce_stage(ce)) {
printf("%s: needs merge\n", ce->name);
- while ((i < active_nr) &&
- ! strcmp(active_cache[i]->name, ce->name))
+ while ((i < get_num_cache_entries(cache)) &&
+ ! strcmp(get_cache_entry(cache, i)->name, ce->name))
i++;
i--;
continue;
@@ -221,10 +221,7 @@
printf("%s: needs update\n", ce->name);
continue;
}
- /* You can NOT just free active_cache[i] here, since it
- * might not be necessarily malloc()ed but can also come
- * from mmap(). */
- active_cache[i] = new;
+ set_cache_entry(cache, new, i);
}
}
@@ -256,7 +253,7 @@
}
}
-static int add_cacheinfo(char *arg1, char *arg2, char *arg3)
+static int add_cacheinfo(struct cache *cache, char *arg1, char *arg2, char *arg3)
{
int size, len;
unsigned int mode;
@@ -279,7 +276,7 @@
memcpy(ce->name, arg3, len);
ce->ce_flags = htons(len);
ce->ce_mode = create_ce_mode(mode);
- return add_cache_entry(ce, allow_add);
+ return add_cache_entry(cache, ce, allow_add);
}
static int remove_lock = 0;
@@ -294,6 +291,7 @@
{
int i, newfd, entries;
int allow_options = 1;
+ struct cache *cache = NULL;
newfd = open(".git/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
if (newfd < 0)
@@ -302,7 +300,8 @@
atexit(remove_lock_file);
remove_lock = 1;
- entries = read_cache();
+ cache = read_cache();
+ entries = get_num_cache_entries(cache);
if (entries < 0)
die("cache corrupted");
@@ -323,11 +322,11 @@
continue;
}
if (!strcmp(path, "--refresh")) {
- refresh_cache();
+ refresh_cache(cache);
continue;
}
if (!strcmp(path, "--cacheinfo")) {
- if (i+3 >= argc || add_cacheinfo(argv[i+1], argv[i+2], argv[i+3]))
+ if (i+3 >= argc || add_cacheinfo(cache, argv[i+1], argv[i+2], argv[i+3]))
die("update-cache: --cacheinfo <mode> <sha1> <path>");
i += 3;
continue;
@@ -338,10 +337,10 @@
fprintf(stderr, "Ignoring path %s\n", argv[i]);
continue;
}
- if (add_file_to_cache(path))
+ if (add_file_to_cache(cache, path))
die("Unable to add %s to database", path);
}
- if (write_cache(newfd, active_cache, active_nr) ||
+ if (write_cache(cache, newfd) ||
rename(".git/index.lock", ".git/index"))
die("Unable to write new cachefile");
Index: write-tree.c
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/write-tree.c (mode:100644 sha1:827809dbddbff6dd8cf842641f6db5ad2f3ae07a)
+++ 38adb888a4c1adfe083f24d4ec51018e0b5a8335/write-tree.c (mode:100644 sha1:ad148b422ffa85d7ecf515e55538c1afa13f17d6)
@@ -29,7 +29,7 @@
#define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
-static int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1)
+static int write_tree(struct cache *cache, int start_pos, const char *base, int baselen, unsigned char *returnsha1)
{
unsigned char subdir_sha1[20];
unsigned long size, offset;
@@ -43,7 +43,7 @@
nr = 0;
do {
- struct cache_entry *ce = cachep[nr];
+ struct cache_entry *ce = get_cache_entry(cache, start_pos + nr);
const char *pathname = ce->name, *filename, *dirname;
int pathlen = ce_namelen(ce), entrylen;
unsigned char *sha1;
@@ -53,16 +53,13 @@
if (baselen >= pathlen || memcmp(base, pathname, baselen))
break;
- sha1 = ce->sha1;
- mode = ntohl(ce->ce_mode);
-
/* Do we have _further_ subdirectories? */
filename = pathname + baselen;
dirname = strchr(filename, '/');
if (dirname) {
int subdir_written;
- subdir_written = write_tree(cachep + nr, maxentries - nr, pathname, dirname-pathname+1, subdir_sha1);
+ subdir_written = write_tree(cache, start_pos + nr, pathname, dirname-pathname+1, subdir_sha1);
nr += subdir_written;
/* Now we need to write out the directory entry into this tree.. */
@@ -72,6 +69,9 @@
/* ..but the directory entry doesn't count towards the total count */
nr--;
sha1 = subdir_sha1;
+ } else {
+ sha1 = ce->sha1;
+ mode = ntohl(ce->ce_mode);
}
if (check_valid_sha1(sha1) < 0)
@@ -87,7 +87,7 @@
memcpy(buffer + offset, sha1, 20);
offset += 20;
nr++;
- } while (nr < maxentries);
+ } while ((start_pos + nr) < get_num_cache_entries(cache));
i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
i -= 5;
@@ -101,16 +101,18 @@
int main(int argc, char **argv)
{
int i, unmerged;
- int entries = read_cache();
unsigned char sha1[20];
+ struct cache *cache = read_cache();
+ int entries;
- if (entries <= 0)
+ if (!cache)
die("write-tree: no cache contents to write");
+ entries = get_num_cache_entries(cache);
/* Verify that the tree is merged */
unmerged = 0;
for (i = 0; i < entries; i++) {
- struct cache_entry *ce = active_cache[i];
+ struct cache_entry *ce = get_cache_entry(cache, i);
if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) {
if (++unmerged > 10) {
fprintf(stderr, "...\n");
@@ -123,7 +125,7 @@
die("write-tree: not able to write tree");
/* Ok, write it out */
- if (write_tree(active_cache, entries, "", 0, sha1) != entries)
+ if (write_tree(cache, 0, "", 0, sha1) != entries)
die("write-tree: internal error");
printf("%s\n", sha1_to_hex(sha1));
return 0;
^ permalink raw reply
* Re: [Gnu-arch-users] Re: [ANNOUNCEMENT] /Arch/ embraces `git'
From: Tom Lord @ 2005-04-21 19:04 UTC (permalink / raw)
To: t8m; +Cc: gnu-arch-dev, git
In-Reply-To: <1114037509.5880.62.camel@perun.redhat.usu>
> Using your suggested indexing method that uses [0:4] as the 1st level key and
[0:3]
> [4:8] as the 2nd level key, I obtain an indexed archive that occupies 159M,
> where the top level contains 18665 1st level keys, the largest first level dir
> contains 5 entries, and all 2nd level dirs contain exactly 1 entry.
That's just a mistake in the spec. The format should probably be
multi-level but, yes, the fanout I suggested is currently quite bogus.
When I write that part of that code (today or tomorrow) I'll fix it.
A few people pointed that out. Thanks.
-t
^ permalink raw reply
* Re: Linux 2.6.12-rc3
From: Petr Baudis @ 2005-04-21 19:09 UTC (permalink / raw)
To: Pavel Machek; +Cc: Linus Torvalds, kernel list, git
In-Reply-To: <20050421190009.GC475@openzaurus.ucw.cz>
Dear diary, on Thu, Apr 21, 2005 at 09:00:09PM CEST, I got a letter
where Pavel Machek <pavel@ucw.cz> told me that...
> Hi!
Hi,
> > > Well, not sure.
> > >
> > > I did
> > >
> > > git track linus
> > > git cancel
> > >
> > > but Makefile still contains -rc2. (Is "git cancel" right way to check
> > > out the tree?)
> >
> > No. git cancel does what it says - cancels your local changes to the
> > working tree. git track will only set that next time you pull from
> > linus, the changes will be automatically merged. (Note that this will
> > change with the big UI change.)
>
> Is there way to say "forget those changes in my repository, I want
> just plain vanilla" without rm -rf?
git cancel will give you "plain last commit". If you need plain vanilla,
the "hard way" now is to just do
commit-id >.git/HEAD
but your current HEAD will be lost forever. Or do
git fork vanilla ~/vanilla linus
and you will have the vanilla tree tracking linus in ~/vanilla.
I'm not yet sure if we should have some Cogito interface for doing this
and what its semantics should be.
> I see quite a lot of problems with fsck-tree. Is that normal?
> (I ran out of disk space few times during different operations...)
Actually, in case your tree is older than about two days, I hope you did
the convert-cache magic or fetched a fresh tree?
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ permalink raw reply
* Re: [PATCH] multi item packed files
From: Krzysztof Halasa @ 2005-04-21 19:28 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Chris Mason, git
In-Reply-To: <Pine.LNX.4.58.0504210832490.2344@ppc970.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Wrong. You most definitely _can_ lose: you end up having to optimize for
> one particular filesystem blocking size, and you'll lose on any other
> filesystem. And you'll lose on the special filesystem of "network
> traffic", which is byte-granular.
If someone needs better on-disk ratio, (s)he can go with 1 KB filesystem
or something like that, without all the added complexity of packing.
If we want to optimize that further, I would try doing it at the
underlying filesystem level. For example, loop-mounted one.
--
Krzysztof Halasa
^ permalink raw reply
* [PATCH] #!/bin/sh --> #!/usr/bin/env bash
From: Alecs King @ 2005-04-21 19:42 UTC (permalink / raw)
To: git
In-Reply-To: <20050421143102.GA830@alc.bsd.st>
On Thu, Apr 21, 2005 at 10:31:02PM +0800, Alecs King wrote:
> On Thu, Apr 21, 2005 at 12:23:26PM +0200, Klaus Robert Suetterlin wrote:
> > Hi,
> >
> > I supply a patch that dehardcodes the path to bash (which is not /bin
> > on all computers) and adds sys/limits.h to provide ULONG_MAX.
>
> Hi, i did a similar patch a while back ago. As for ULONG_MAX, not every
> sytem has <sys/limits.h>, i think <limits.h> is the rite place to go.
>
> The patch below tested on both debian and fbsd.
>
> [snip]
And as for bash, only gitdiff-do and gitlog.sh 'explicitly' use bash
instead of /bin/sh. On most Linux distros, /bin/sh is just a symbolic
link to bash. But not on some others. I found gitlsobj.sh could not
work using a plain /bin/sh on fbsd. To make life easier, i think it
might be better if we all explicitly use bash for all shell scripts.
patch below assumes the patch above has been applied.
commit 341cd1241815178d567ce612c97c2bb5a663021a
tree abb16c39fe8354383b632f7fa9dd4611ff66e1d1
parent 2deea74db72fb57a8b80e7945f23814112b22723
author Alecs King <alecsk ! gmail d@t com> 1114107613 +0800
committer Alecs King <alecsk ! gmail d@t com> 1114107613 +0800
Explicitly use bash
#!/bin/sh ==> #!/usr/bin/env bash
Index: gitXlntree.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitXlntree.sh (mode:100755 sha1:c474913d09906739d8175f1b430720a3ac67e798)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitXlntree.sh (mode:100755 sha1:adc01eeb56f394a6168ae1f6f1fe4c40e1c2aecc)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Provide an independent view to the objects database.
# Copyright (c) Petr Baudis, 2005
Index: gitXnormid.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitXnormid.sh (mode:100755 sha1:c0d53afabe8662ebfc3c697faf08b0a2b43c93f7)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitXnormid.sh (mode:100755 sha1:9b311aca57bd8b7012f45d730c6fd26d5fb5d2b2)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Internal: Normalize the given ID to a tree ID.
# Copyright (c) Petr Baudis, 2005
Index: gitadd.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitadd.sh (mode:100755 sha1:3f5e9a2d6b452d596cd853f1585113bdb356a2e3)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitadd.sh (mode:100755 sha1:6feb7372e95be4546af17e0c6b55d10c9a1c441d)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Add new file to a GIT repository.
# Copyright (c) Petr Baudis, 2005
Index: gitaddremote.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitaddremote.sh (mode:100755 sha1:a117b9e8d14b977143caa48c26fc51794e8b7135)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitaddremote.sh (mode:100755 sha1:bccaa9068063b07d13012477861c6706b7cd40a6)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Add new "remote" to the GIT repository.
# Copyright (c) Petr Baudis, 2005
Index: gitapply.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitapply.sh (mode:100755 sha1:7703809dc0743c6e4c1fa5b7d922a4efc16b4276)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitapply.sh (mode:100755 sha1:794ea5ed6acdd34e34742a17cbd784dcbf738289)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Apply a diff generated by git diff.
# Copyright (c) Petr Baudis, 2005
Index: gitcancel.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitcancel.sh (mode:100755 sha1:74b4083d67eda87d88a6f92c6c66877bba8bda8a)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitcancel.sh (mode:100755 sha1:c320ee98e2ed0b13a68de3b2ec4e4a8451b5189a)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Cancels current edits in the working tree.
# Copyright (c) Petr Baudis, 2005
Index: gitcommit.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitcommit.sh (mode:100755 sha1:a13bef2c84492ed75679d7d52bb710df35544f8a)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitcommit.sh (mode:100755 sha1:0207f402cc5107de2a4685f6fcade081c41d91e9)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Commit into a GIT repository.
# Copyright (c) Petr Baudis, 2005
Index: gitdiff.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitdiff.sh (mode:100755 sha1:8e14a868f513f4ec524a2c8974c8d202c6824038)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitdiff.sh (mode:100755 sha1:e27915d4172717ddd4d01269877312b08ed2acc4)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Make a diff between two GIT trees.
# Copyright (c) Petr Baudis, 2005
Index: gitexport.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitexport.sh (mode:100755 sha1:5b94424beca55ffe6b5535e4975e6e63c1bae672)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitexport.sh (mode:100755 sha1:428cd9d845598e320556729b6098505132a4e7c4)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Exports a particular revision from a GIT repository.
# Copyright (c) Johannes E. Schindelin, 2005
Index: gitfork.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitfork.sh (mode:100755 sha1:b827c3037ac4f3cdfb6708bf8edb60944f59318a)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitfork.sh (mode:100755 sha1:ce26f985ebb48b6a3127ac8afd427ba30ba5668a)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Create a branch sharing the objects database.
# Copyright (c) Petr Baudis, 2005
Index: gitinit.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitinit.sh (mode:100755 sha1:9905166859827893e326b01bdc3970ff6d51064d)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitinit.sh (mode:100755 sha1:bc00e9ee709aabeb4764b77ac4e5a19212fa5857)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Initialize a GIT repository.
# Copyright (c) Petr Baudis, 2005
Index: gitls.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitls.sh (mode:100755 sha1:c8d2220eae66addd49493cdb32af21b6c0217b23)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitls.sh (mode:100755 sha1:a05883b09512bd1d1fe31e1c6d43f01a395c58a1)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# List contents of a particular tree in a GIT repository.
# Copyright (c) Petr Baudis, 2005
Index: gitlsobj.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitlsobj.sh (mode:100755 sha1:423a1bc7476bad7bf40f1b3ddb03d83fdcf1f9cd)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitlsobj.sh (mode:100755 sha1:3f4426eeac7cc5ad51a46632319814fbf62b2cc3)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# List objects of the GIT repository.
# Copyright (c) Randy Dunlap, 2005
Index: gitlsremote.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitlsremote.sh (mode:100755 sha1:2212be93aaa8a371e83cafb69fa21a7a1b24ed13)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitlsremote.sh (mode:100755 sha1:29657d7a899ffb425a36ec04bf1c62aa1ecc14d7)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Lists remote GIT repositories
# Copyright (c) Steven Cole 2005
Index: gitmerge-file.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitmerge-file.sh (mode:100755 sha1:820de487babb76ce419b6823c8fe4c58608d0c8c)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitmerge-file.sh (mode:100755 sha1:237186eaefc4a503c386e4a0e7c28818e6704db7)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Copyright (c) Linus Torvalds, 2005
#
Index: gitmerge.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitmerge.sh (mode:100755 sha1:bc68f6cda84cbf1165d71b17d6207b3c46a8cad4)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitmerge.sh (mode:100755 sha1:92e552700a40c5e1f7339c9b1f261cb39206a3c3)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Merge a branch to the current tree.
# Copyright (c) Petr Baudis, 2005
Index: gitpatch.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitpatch.sh (mode:100755 sha1:580e3e6b0c23625abd2288be35ee33a787a1ba3c)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitpatch.sh (mode:100755 sha1:fd00c88133c874ac71a90a045a313363f9f22350)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Make a patch from a given commit.
# Copyright (c) Petr Baudis, 2005
Index: gitpull.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitpull.sh (mode:100755 sha1:0cafc0270ea91aaf099f398b7e5cd360be9ea086)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitpull.sh (mode:100755 sha1:7f847f39e0b2aa150fe195d8d4f6f0d62487ae72)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Pulls changes from "remote" to the local GIT repository.
# Copyright (c) Petr Baudis, 2005
Index: gitrm.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitrm.sh (mode:100755 sha1:3fa31f9a1ae843dcb184b8371ff60f626e8820b3)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitrm.sh (mode:100755 sha1:e014b979ea7b8f7ae69eabc7dd146c8a7f286d19)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Remove a file from a GIT repository.
# Copyright (c) Petr Baudis, 2005
Index: gitseek.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitseek.sh (mode:100755 sha1:b80969a4ba040202827ea7532235abab15ca9392)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitseek.sh (mode:100755 sha1:035b78a93307da8f67f7447ed3a182a6d17d2c50)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Seek the working tree to a given commit.
# Copyright (c) Petr Baudis, 2005
Index: gitstatus.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gitstatus.sh (mode:100755 sha1:7d5209ea838106eb2ab5bde2704997508a22a4e8)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gitstatus.sh (mode:100755 sha1:9cfb2ce947082002cff3e5497ca2a994c4bbb101)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Show status of entries in your working tree.
# Copyright (c) Petr Baudis, 2005
Index: gittag.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gittag.sh (mode:100755 sha1:9e1e200deda54b2401d6d685f0d5305cfbfa38ca)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gittag.sh (mode:100755 sha1:19c7f3ecffa55f117c27c9a1d8de67f65805f1c7)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Mark certain commit by a tag.
# Copyright (c) Petr Baudis, 2005
Index: gittrack.sh
===================================================================
--- 0c92ac3af53457b6b9651cf82d98ce3a7b166dcd/gittrack.sh (mode:100755 sha1:7509d4adb2b2c50cd2acdf9126fc57cff79e6009)
+++ abb16c39fe8354383b632f7fa9dd4611ff66e1d1/gittrack.sh (mode:100755 sha1:bdf33313f4ad0c4f7b6b235fbc68fc85f226a33a)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
#
# Makes your working tree track the given branch.
# Copyright (c) Petr Baudis, 2005
--
Alecs King
^ permalink raw reply
* Mozilla SHA1 implementation
From: Linus Torvalds @ 2005-04-21 19:48 UTC (permalink / raw)
To: Edgar Toernig, Git Mailing List
In-Reply-To: <20050418055824.42d621b8.froese@gmx.de>
I've just integrated the Mozilla SHA1 library implementation that Adgar
Toernig sent me into the standard git archive (but I did the integration
differently).
The Mozilla SHA1 code is copyright Paul Kocher and Cryptography Research,
and is released under a dual MPL/GPL license. Git obviously uses it in the
GPL version, but I left the MPL choice there too, so that those two files
(that are in a subdirectory of its own) will continue to be dual-licensed.
NOTE! I left git using the openssl libraries by default, and this is a
built-time choice in the makefile. You can choose the Mozilla SHA1
implementation by doing
make clean
MOZILLA_SHA1=1 make
make install
but I suspect that anybody that has openssl installed and is working on an
x86 is much better off with the i586-optimized openssl version. But if you
don't have openssl by default, or if you don't like openssl for some other
reason, you now have a nice easy choice.
Interestingly, the Mozilla SHA1 code is about twice as fast as the openssl
code on my G5, and judging by the disassembly, it's because it's much
simpler. I think the openssl people have unrolled all the loops totally,
which tends to be a disaster on any half-way modern CPU. But hey, it could
be something as simple as optimization flags too.
Linus
^ permalink raw reply
* [RFC] A suggestion for more versatile naming conventios in the object database
From: Imre Simon @ 2005-04-21 19:51 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In the transition from git-0.04 to git-0.5 (Linus' track) the naming
convention of files in the object database has been changed: a file's
name passed from the sha1 of its contents to the sha1 of its contents
*before* compression.
This change was preceded by a long discussion hence both conventions
have arguments for and against.
I would like to suggest to adopt a more versatile solution:
preserve the pure sha1 based names for the sha1 sum of the file's
contents. I mean,
(*) for files with name xy/z{38} their sha1 sum is xyz{38}
allow other files (or links) with names of the form
xy/z{38}.EXTENSION
where for every EXTENSION the file's content would be the EXTENSION
representation of the file xy/z{38} . For every representation type
EXTENSION there should be procedures to derive the file xy/z{38}
from the name xy/z{38}.EXTENSION and vice-versa (assuming that the
representation type EXTENSION cares about the contents of file
xy/z{38}).
Let me give two examples:
all the files in the object database of git-0.04 are just fine, they
satisfy axiom (*)
the name of every file xy/z{38} in the git-0.5 data base should be
changed to xy/z{38}.g assuming that we will use EXTENSION g as the
git representation type. The conversion algorithms would be:
cat-file `cat-file -t xyz{38}` xyz{38} to obtain the contents
represented by xy/z{38}.g whose sha1 is xyz{38}
and a utility program has to be written to check whether a given
file F, is a valid contents as far as git is concerned and in
case it is compute its sha1 sum xyz{38} and also comute the file
the file xy/z{38}.g .
So, what are the advantages of this further complication? I see these ones:
git is separated from the idea of sha1 addressable contents, which
indeed is an idea larger than git itself. This same or similar
addressing schemes can (and most probably will) be applied to other
contents besides SCMs. An example would be a digital library of
scientific papers in pdf together with its OAI compliant meta data
(don't bother if you are not familiar with these terms, it is just
an example and I am sure you are able to come up with many other
examples where a sha1 addressable data base would be interesting)
all these uses could share common backup schemes where axiom (*)
would be enforced. One could think of a shared p2p database of
repositories of sha1 addressed contents of all kinds. This might be
important because, in general, the contents of xyz{38} cannot be
reconstructed from its name. The way to defend against file system
corruption is replication. Why not share these backup databases?
it would be easier to experiment with other compression schemes or
other proposals for meta data in git itself.
it would be easier to experiment with the factorization of common
chunks of contents, an idea very close to the secret of rsync's
amazing efficiency.
Well, that's the proposal. I would be happy to hear comments!
Cheers,
Imre Simon
PS: the way it is, the git-0.5 README file is inconsistent. The naming
change is not reflected in the README file which in many places states
that the sha1 sum of file xy/z{38} is xyz{38}.
^ permalink raw reply
* Re: [PATCH] Allow "git cancel" to change branches
From: Pavel Roskin @ 2005-04-21 20:00 UTC (permalink / raw)
To: Matthias Urlichs; +Cc: git
In-Reply-To: <E1DObsr-0006Au-MA@server.smurf.noris.de>
Hi, Matthias!
On Thu, 2005-04-21 at 23:31 +1000, Matthias Urlichs wrote:
> "git cancel" may not be named correctly for this job, but it does almost
> everything you'd need for switching between one branch and another
> within a repository, so...
This functionality is badly needed, but "git cancel" should probably
remain what it is.
> +if [ "$1" ] ; then
> + test -f .git/heads/$1 || cp .git/HEAD .git/heads/$1
> + ln -sf "heads/$1" .git/HEAD
> +fi
Considering that the patch is essentially just this block of code, it
could be (in the first approximation) a separate command, e.g. "git
switch", that would call "git cancel" if needed.
But let's consider the fact that "git cancel" removes all local changes.
That's quite a serious side effect. I don't always want to remove local
changes when I switch between branches in CVS. Many users would prefer
git to do a merge.
I think that "git track" needs to be redesigned. There are at least
three properties of the working directory (related to branch tracking)
that users may want to change:
1) Where new revisions are pulled from. It could be more than one
branch (ideal implementation - with several copies of rsync run
simultaneously).
2) What branch is "checked out" to the working directory, i.e. what
branch would "git cancel" restore.
3) Whether new changes are merged automatically.
I suggest following syntax:
git track -b WORKING-BRANCH [--cancel] [--active|--passive]
[TRACK-BRANCH...|--notrack]
--cancel would cancel changes rather than merge when the current branch
changes.
--active enables automerge, --passive disables it
Empty list of branches to track should not disable tracking. Only
--notrack should do it.
Then your "git cancel BRANCH" would become:
git track -b BRANCH --cancel
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: [PATCH] multi item packed files
From: Linus Torvalds @ 2005-04-21 20:07 UTC (permalink / raw)
To: Krzysztof Halasa; +Cc: Chris Mason, git
In-Reply-To: <m3u0m0q69a.fsf@defiant.localdomain>
On Thu, 21 Apr 2005, Krzysztof Halasa wrote:
>
> If someone needs better on-disk ratio, (s)he can go with 1 KB filesystem
> or something like that, without all the added complexity of packing.
I really think the argument that "you can use filesystem feature XYZ" is
bogus.
I know that I'm not willing to switch filesystems on a whim. I suspect
nobody else is either. I'm not going to create a loopback filesystem just
for git, it's just too much pain.
And dammit, if I'm the original author and likely biggest power-user, and
_I_ can't be bothered to use special filesystems, then who can? Nobody.
This is why I absolutely do not believe in arguments like "if your
filesystem doesn't do tail packing, you shouldn't use it" or "if your
don't have name hashing enabled in your filesystem it's broken".
I'm perfectly willing to optimize for the common case, but that's as far
as it goes. I do not want to make fundamental design decisions that depend
on the target filesystem having some particular feature.
(I'll happily make decisions that say that the target _OS_ has to have a
particular feature, though. I'll require a sane base-level for
functionality, but not something like filesystem details).
Linus
^ permalink raw reply
* Re: git-viz tool for visualising commit trees
From: Olivier Andrieu @ 2005-04-21 20:14 UTC (permalink / raw)
To: mingo; +Cc: git
In-Reply-To: <20050421144716.GA15136@elte.hu>
> Ingo Molnar [Thu, 21 Apr 2005]:
> I just checked how the kernel repository looks like with it, and
> i'm impressed! The GUI is top-notch, and the whole graph output and
> navigation is very mature visually. Kudos!
Thanks !
> - there doesnt seem to be any performance difference between non-colored
> and colored rendering - so you might as well want to make 'color by
> author' (or color by branch) the default coloring, instead of
> uncolored?
It has to call `cat-file commit' for each commit id to get the author
... it's just that's a lot of forks.
> - naming the boxes by key is quite meaningless. It would be more
> informative to see the author's email shortcuts in the boxes. Also, it
> would be nice to see some simple graphical feedback about the size and
> scope of a changeset, without having to zoom on it.
That's interesting. What do you mean exactly by scope ?
> i guess you know it, and i'm definitely not complaining about prototype
> code, but rendering is quite slow: drawing the 340 changesets in the
> current kernel repository takes 15 seconds on a 2 GHz P4. Drawing the
> full kernel history (63,000 changesets) would take more than 45 minutes
> on this box.
>
> the current rate of kernel development is ~2000 changesets per month, so
> drawing the kernel history will get 3 seconds slower every day - it will
> exceed 1 minute in 20 days, so this will become a pressing issue quite
> soon i suspect.
Right, it is slow. From what I could understand with a bit of
profiling, the problem is with the "text" canvas item for the boxes'
labels. I guess libgnomecanvas isn't using Pango properly or
something: it lookups the font with fontconfig each time I create such
an item. I'm not sure what I can do about this.
Also, there's a -noaa option that draws an non-antialiased canvas :
it's noticeably faster (and uglier too).
> Ingo Molnar [Thu, 21 Apr 2005]:
> another thing, when i 'zoom out' of the graph far away (so that the
> whole graph becomes visible on the screen), i'm getting lots of such
> error messages:
>
> *** attempt to put segment in horiz list twice
Yes, this message must come from one of the libraries (libart most
probably)
> Ingo Molnar [Thu, 21 Apr 2005]:
> is the 'diff with ancestor' feature supposed to work at this early
> stage? (it just does nothing when i click on it. It correctly
> offers two ancestors for merge points, but does nothing there
> either.)
It works with Petr Baudis' git-pasky (it calls `git diff'). I don't
know how to do that with the canonical git.
Thanks for the suggestions,
--
Olivier
^ permalink raw reply
* Re: [PATCH] multi item packed files
From: Chris Mason @ 2005-04-21 20:22 UTC (permalink / raw)
To: Krzysztof Halasa; +Cc: Linus Torvalds, git
In-Reply-To: <m3u0m0q69a.fsf@defiant.localdomain>
On Thursday 21 April 2005 15:28, Krzysztof Halasa wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
> > Wrong. You most definitely _can_ lose: you end up having to optimize for
> > one particular filesystem blocking size, and you'll lose on any other
> > filesystem. And you'll lose on the special filesystem of "network
> > traffic", which is byte-granular.
>
> If someone needs better on-disk ratio, (s)he can go with 1 KB filesystem
> or something like that, without all the added complexity of packing.
>
> If we want to optimize that further, I would try doing it at the
> underlying filesystem level. For example, loop-mounted one.
Shrug, we shouldn't need help from the kernel for something like this. git as
a database hits worst case scenarios for almost every FS.
We've got:
1) subdirectories with lots of files
2) wasted space for tiny files
3) files that are likely to be accessed together spread across the whole disk
One compromise for SCM use would be one packed file per commit, with an index
that lets us quickly figure out which commit has a particular version of a
given file. My hack gets something close to that (broken into 32k chunks for
no good reason), and the index to find a given file is just the git directory
tree.
But my code does hide the fact that we're packing things from most of the git
interfaces. So I can almost keep a straight face while claiming to be true
to the original git design...almost. The whole setup is far from perfect,
but it is one option for addressing points 2 & 3 above.
-chris
^ permalink raw reply
* Re: Pasky problem with 'git init URL'
From: Petr Baudis @ 2005-04-21 20:29 UTC (permalink / raw)
To: Martin Schlemmer; +Cc: GIT Mailing Lists
In-Reply-To: <1114100518.17551.31.camel@nosferatu.lan>
Dear diary, on Thu, Apr 21, 2005 at 06:21:58PM CEST, I got a letter
where Martin Schlemmer <azarah@nosferatu.za.org> told me that...
> Hi,
Hi,
> Just pulled linux-2.6.git, and got this:
>
> ----
> New branch: 3a6fd752a50af92765853879f4a11cc0cfcd0320
> Tracked branch, applying changes...
> Merging 4d78b6c78ae6d87e4c1c8072f42efa716f04afb9 -> 3a6fd752a50af92765853879f4a11cc0cfcd0320
> to a2755a80f40e5794ddc20e00f781af9d6320fafb...
>
> Enter commit message, terminated by ctrl-D on a separate line:
> Merge with 3a6fd752a50af92765853879f4a11cc0cfcd0320
> ----
>
> Weird thing was that I made no changes.
did you compensate for the renamed hashes? Didn't you before update from
some very old git-pasky version?
Actually, did you do that git init _after_ the unsuccessful pull, or
before?
> Digging a bit deeper, I saw that .git/HEAD was a symlink
> to .git/heads/master, and the tracked branch was 'origin'. Due to the
> fact that Linus only have a .git/heads/master on his rsync, and this
> thus updated to the new sha1, but the 'origin' (and tracked) head is
> still pointing to an older sha1 caused this confusion.
Duh. The remote branch always grabs the HEAD over there; you don't need
to care about the various branches over there, and you really do not
*want* to care. Actually I might add some ^branchname to the rsync URL,
to be able to refer to particular branches inside of the repository.
> I replicated the linux tree via:
>
> ----
> git init URL
> ----
>
> So I had a look at gitinit.sh, which first creates the .git/heads/master
> and symlinks HEAD to it, then on seeing a URL was supplied, creates
> a .git/heads/origin, track it, but do *not* change the .git/HEAD
> symlink ... Is this intended? I see also that gittrack.sh do not update
> the HEAD symlink ... Is this also intended?
Yes.
You never work directly on the remote branch. Ever. That's what this
tracking stuff is for; you set up a local branch which follows the
remote one.
Otherwise, you fork to two trees, one is remote branch, second is local
branch, and you do git pull remotebranch in the second. You are in
trouble now. Also, if you do some local commit on the remote branch,
what would happen? This kind of stuff is why I decided that you just
cannot work on remote branches directly.
> The last option however brings a problem or two. First, how do you do
> the multi-head thing? Maybe add a command 'git lsheads' (and while at
> it, also add 'git lstags'?)? Secondly, if there was more than one head,
Perhaps it would be useful to have some "command classes" (with at least
cg-*-(add|ls|rm)), like:
cg-branch-ls
cg-remote-rm
cg-tag-add
> the local copy needs to be checked out ... don't know if 'git cancel' is
> the logical thing the user will think to do ('git clone' perhaps?) ...
I don't know what do you mean here.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ permalink raw reply
* Re: [Gnu-arch-users] Re: [GNU-arch-dev] [ANNOUNCEMENT] /Arch/ embraces `git'
From: Tom Lord @ 2005-04-21 20:35 UTC (permalink / raw)
To: t8m; +Cc: duchier, gnu-arch-dev, talli, git, torvalds
In-Reply-To: <1114037509.5880.62.camel@perun.redhat.usu>
> Yes, it really doesn't make much sense to have so big keys on the
> directories.
It's official... i'm blushing wildly.... thank you for the various
replies that pointed out my thinko.
That part of my spec hasn't been coded yet --- i just wrote text. It
really was the silly late-night error of sort: "hmm...let's see, 4 hex
digits plus 4 hex digits .... that's 16 bits.... sounds about right."
Really, I'll fix it.
-t
^ permalink raw reply
* Re: [Gnu-arch-users] Re: [ANNOUNCEMENT] /Arch/ embraces `git'
From: Tom Lord @ 2005-04-21 20:39 UTC (permalink / raw)
To: duchier; +Cc: gnu-arch-users, gnu-arch-dev, git
In-Reply-To: <867jixata5.fsf@speedy.lifl.fr>
> [your 0:3/4:7 directory hierarchy is horked]
Absolutely. Made a dumb mistake the night I wrote that spec
and embarassed that I initially defended it. I had an arithmetic
error. Thanks, this time, for your persistence in pointing it out.
-t
^ permalink raw reply
* [PATCH] Docs update
From: David Greaves @ 2005-04-21 20:40 UTC (permalink / raw)
To: Petr Baudis; +Cc: GIT Mailing Lists
[-- Attachment #1: Type: text/plain, Size: 108 bytes --]
Added commit-tree, diff-cache and environment info
Signed-off-by: David Greaves <david@dgreaves.com>
---
[-- Attachment #2: README.reference.patch2 --]
[-- Type: text/plain, Size: 7471 bytes --]
Index: README.reference
===================================================================
--- c0260bfb82da04aeff4e598ced5295d6ae2e262d/README.reference (mode:100644 sha1:8186a561108d3c62625614272bd5e2f7d5826b4b)
+++ 5f204110aef2538fdc512e09e4a075b3afac8eff/README.reference (mode:100644 sha1:b5fc4fb969ec3f52877408c8df4ba131a8c4a7b2)
@@ -109,12 +109,173 @@
################################################################
commit-tree
- commit-tree <sha1> [-p <sha1>]* < changelog
+ commit-tree <sha1> [-p <parent sha1>...] < changelog
+Creates a new commit object based on the provided tree object and
+emits the new commit object id on stdout. If no parent is given then
+it is considered to be an initial tree.
+
+A commit object usually has 1 parent (a commit after a change) or 2
+parents (a merge) although there is no reason it cannot have more than
+2 parents.
+
+While a tree represents a particular directory state of a working
+directory, a commit represents that state in "time", and explains how
+to get there.
+
+Normally a commit would identify a new "HEAD" state, and while git
+doesn't care where you save the note about that state, in practice we
+tend to just write the result to the file ".git/HEAD", so that we can
+always see what the last committed state was.
+
+Options
+
+<sha1>
+ An existing tree object
+
+-p <parent sha1>
+ Each -p indicates a the id of a parent commit object.
+
+
+Commit Information
+
+A commit encapsulates:
+ all parent object ids
+ author name, email and date
+ committer name and email and the commit time.
+
+If not provided, commit-tree uses your name, hostname and domain to
+provide author and committer info. This can be overridden using the
+following environment variables.
+ AUTHOR_NAME
+ AUTHOR_EMAIL
+ AUTHOR_DATE
+ COMMIT_AUTHOR_NAME
+ COMMIT_AUTHOR_EMAIL
+(nb <,> and CRs are stripped)
+
+A commit comment is read from stdin (max 999 chars)
+
+see also: write-tree
+
+
+################################################################
+diff-cache
+ diff-cache [-r] [-z] <tree/commit sha1>
+
+Compares the content and mode of the blobs found via a tree object
+with the content of the current cache and, optionally, the stat state
+of the file on disk.
+
+(This is basically a special case of diff-tree that works with the
+current cache as the first tree.)
+
+<tree sha1>
+ The id of a tree or commit object to diff against.
+
+-r
+ recurse
+
+-z
+ /0 line termintation on output
+
+--cached
+ do not consider the on-disk file at all
+
+Output format:
+
+For files in the tree but not in the cache
+-<mode> <type> <sha1> <filename>
+
+For files in the cache but not in the tree
++<mode> <type> <sha1> <filename>
+
+For files that differ:
+*<tree-mode>-><cache-mode> <type> <tree sha1>-><cache sha1> path/<filename>
+
+In the special case of the file being changed on disk and out of sync with the cache, the sha1
+
+Operating Modes
+You can choose whether you want to trust the index file entirely
+(using the "--cached" flag) or ask the diff logic to show any files
+that don't match the stat state as being "tentatively changed". Both
+of these operations are very useful indeed.
+
+Cached Mode
+If --cached is specified, it allows you to ask:
+ show me the differences between HEAD and the current index
+ contents (the ones I'd write with a "write-tree")
+
+For example, let's say that you have worked on your index file, and are
+ready to commit. You want to see eactly _what_ you are going to commit is
+without having to write a new tree object and compare it that way, and to
+do that, you just do
+
+ diff-cache --cached $(cat .git/HEAD)
+
+Example: let's say I had renamed "commit.c" to "git-commit.c", and I had
+done an "upate-cache" to make that effective in the index file.
+"show-diff" wouldn't show anything at all, since the index file matches
+my working directory. But doing a diff-cache does:
+ torvalds@ppc970:~/git> diff-cache --cached $(cat .git/HEAD)
+ -100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 commit.c
+ +100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 git-commit.c
+
+And as you can see, the output matches "diff-tree -r" output (we
+always do "-r", since the index is always fully populated
+??CHECK??).
+You can trivially see that the above is a rename.
+
+In fact, "diff-tree --cached" _should_ always be entirely equivalent to
+actually doing a "write-tree" and comparing that. Except this one is much
+nicer for the case where you just want to check where you are.
+
+So doing a "diff-cache --cached" is basically very useful when you are
+asking yourself "what have I already marked for being committed, and
+what's the difference to a previous tree".
+
+Non-cached Mode
+
+The "non-cached" mode takes a different approach, and is potentially
+the even more useful of the two in that what it does can't be emulated
+with a "write-tree + diff-tree". Thus that's the default mode. The
+non-cached version asks the question
+
+ "show me the differences between HEAD and the currently checked out
+ tree - index contents _and_ files that aren't up-to-date"
+
+which is obviously a very useful question too, since that tells you what
+you _could_ commit. Again, the output matches the "diff-tree -r" output to
+a tee, but with a twist.
+
+The twist is that if some file doesn't match the cache, we don't have a
+backing store thing for it, and we use the magic "all-zero" sha1 to show
+that. So let's say that you have edited "kernel/sched.c", but have not
+actually done an update-cache on it yet - there is no "object" associated
+with the new state, and you get:
+
+ torvalds@ppc970:~/v2.6/linux> diff-cache $(cat .git/HEAD )
+ *100644->100664 blob 7476bbcfe5ef5a1dd87d745f298b831143e4d77e->0000000000000000000000000000000000000000 kernel/sched.c
+
+ie it shows that the tree has changed, and that "kernel/sched.c" has is
+not up-to-date and may contain new stuff. The all-zero sha1 means that to
+get the real diff, you need to look at the object in the working directory
+directly rather than do an object-to-object diff.
+
+NOTE! As with other commands of this type, "diff-cache" does not actually
+look at the contents of the file at all. So maybe "kernel/sched.c" hasn't
+actually changed, and it's just that you touched it. In either case, it's
+a note that you need to upate-cache it to make the cache be in sync.
+
+NOTE 2! You can have a mixture of files show up as "has been updated" and
+"is still dirty in the working directory" together. You can always tell
+which file is in which state, since the "has been updated" ones show a
+valid sha1, and the "not in sync with the index" ones will always have the
+special all-zero sha1.
################################################################
diff-tree
- diff-tree [-r] [-z] <tree sha1> <tree sha1>
+ diff-tree [-r] [-z] <tree sha1> <tree sha1>
################################################################
@@ -156,3 +317,23 @@
unpack-file
unpack-file.c <sha1>
+
+
+git Environment Variables
+GIT_CACHE_DIRECTORY
+AUTHOR_NAME
+AUTHOR_EMAIL
+AUTHOR_DATE
+RSYNC_FLAGS
+GIT_INDEX_FILE
+
+
+.git Repository Files
+
+.git/HEAD
+This file always contains the last (head) commit object created for this branch of the repository.
+(Usually symlinked to a file in .git/heads/)
+
+.git/heads/
+This directory contains a file for each branch of the .git repository.
+The name of the file is the friendly name of the branch (eg pasky)
^ permalink raw reply
* Re: [PATCH] Add "git push"
From: Petr Baudis @ 2005-04-21 20:41 UTC (permalink / raw)
To: Matthias Urlichs; +Cc: git
In-Reply-To: <20050421124333.AB2CE7F887@smurf.noris.de>
Dear diary, on Thu, Apr 21, 2005 at 02:43:33PM CEST, I got a letter
where Matthias Urlichs <smurf@smurf.noris.de> told me that...
> This patch adds the ability to "git push", as the obvious converse of
> "git pull".
While lack of locking is a problem for git-pasky too, for this git push
it is a downright disaster waiting to happen. It might be also a good
idea to check for remote 'blocked' file, which must exist and contain
only a "pushtree" line. This is so that no (sensible) real working tree
is attached to it, which would be a disaster for it too.
You probably don't want to allow pushing if your local tree is blocked.
And you want to allow pushing only when HEAD is your ancestor. (Helper
tool wanted for this - we need this in git merge badly too.)
BTW, it contains some unrelated and seemingly irrelevant tracking stuff.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox