diff options
author | Linus Torvalds <torvalds@osdl.org> | 2005-11-26 09:38:20 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-11-28 23:00:14 -0800 |
commit | 3c5e8468a93cdb427b4c4a129339e80e1813e5c0 (patch) | |
tree | f924da722242e90150ba1b56fb85bc1f2317ed03 /tree.c | |
parent | 9ef2b3cbf62d15aa0312bde349347873d7c0f399 (diff) | |
download | git-3c5e8468a93cdb427b4c4a129339e80e1813e5c0.tar.gz git-3c5e8468a93cdb427b4c4a129339e80e1813e5c0.tar.xz |
ls-tree: major rewrite to do pathspec
git-ls-tree should be rewritten to use a pathspec the same way everybody
else does. Right now it's the odd man out: if you do
git-ls-tree HEAD divers/char drivers/
it will show the same files _twice_, which is not how pathspecs in general
work.
How about this patch? It breaks some of the git-ls-tree tests, but it
makes git-ls-tree work a lot more like other git pathspec commands, and it
removes more than 150 lines by re-using the recursive tree traversal (but
the "-d" flag is gone for good, so I'm not pushing this too hard).
Linus
Diffstat (limited to 'tree.c')
-rw-r--r-- | tree.c | 34 |
1 files changed, 24 insertions, 10 deletions
@@ -9,9 +9,16 @@ const char *tree_type = "tree"; static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage) { - int len = strlen(pathname); - unsigned int size = cache_entry_size(baselen + len); - struct cache_entry *ce = xmalloc(size); + int len; + unsigned int size; + struct cache_entry *ce; + + if (S_ISDIR(mode)) + return READ_TREE_RECURSIVE; + + len = strlen(pathname); + size = cache_entry_size(baselen + len); + ce = xmalloc(size); memset(ce, 0, size); @@ -67,9 +74,10 @@ static int match_tree_entry(const char *base, int baselen, const char *path, uns return 0; } -static int read_tree_recursive(void *buffer, unsigned long size, - const char *base, int baselen, - int stage, const char **match) +int read_tree_recursive(void *buffer, unsigned long size, + const char *base, int baselen, + int stage, const char **match, + read_tree_fn_t fn) { while (size) { int len = strlen(buffer)+1; @@ -86,6 +94,14 @@ static int read_tree_recursive(void *buffer, unsigned long size, if (!match_tree_entry(base, baselen, path, mode, match)) continue; + switch (fn(sha1, base, baselen, path, mode, stage)) { + case 0: + continue; + case READ_TREE_RECURSIVE: + break;; + default: + return -1; + } if (S_ISDIR(mode)) { int retval; int pathlen = strlen(path); @@ -106,22 +122,20 @@ static int read_tree_recursive(void *buffer, unsigned long size, retval = read_tree_recursive(eltbuf, eltsize, newbase, baselen + pathlen + 1, - stage, match); + stage, match, fn); free(eltbuf); free(newbase); if (retval) return -1; continue; } - if (read_one_entry(sha1, base, baselen, path, mode, stage) < 0) - return -1; } return 0; } int read_tree(void *buffer, unsigned long size, int stage, const char **match) { - return read_tree_recursive(buffer, size, "", 0, stage, match); + return read_tree_recursive(buffer, size, "", 0, stage, match, read_one_entry); } struct tree *lookup_tree(const unsigned char *sha1) |