diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-14 11:26:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-14 11:26:31 -0700 |
commit | 0ca14a57f159fc9d0923dbb122705dd8d6a45488 (patch) | |
tree | e0c7f2bb000535b6bb919e5b3b1deae9242290bc /tree.c | |
parent | d48a72f337fa8edfb7a09e620e75cbbb2a5fe836 (diff) | |
download | git-0ca14a57f159fc9d0923dbb122705dd8d6a45488.tar.gz |
Start adding interfaces to read in partial trees
The same way "git-diff-tree" can limit its output to just a set of matches,
we can read in just a partial tree for comparison purposes.
Diffstat (limited to 'tree.c')
-rw-r--r-- | tree.c | 55 |
1 files changed, 51 insertions, 4 deletions
@@ -21,8 +21,51 @@ static int read_one_entry(unsigned char *sha1, const char *base, int baselen, co return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK); } +static int match_tree_entry(const char *base, int baselen, const char *path, unsigned int mode, char **paths) +{ + char *match; + int pathlen; + + if (!paths) + return 1; + pathlen = strlen(path); + while ((match = *paths++) != NULL) { + int matchlen = strlen(match); + + if (baselen >= matchlen) { + /* If it doesn't match, move along... */ + if (strncmp(base, match, matchlen)) + continue; + /* The base is a subdirectory of a path which was specified. */ + return 1; + } + + /* Does the base match? */ + if (strncmp(base, match, baselen)) + continue; + + match += baselen; + matchlen -= baselen; + + if (pathlen > matchlen) + continue; + + if (matchlen > pathlen) { + if (match[pathlen] != '/') + continue; + if (!S_ISDIR(mode)) + continue; + } + + if (strncmp(path, match, pathlen)) + continue; + } + return 0; +} + static int read_tree_recursive(void *buffer, unsigned long size, - const char *base, int baselen, int stage) + const char *base, int baselen, + int stage, char **match) { while (size) { int len = strlen(buffer)+1; @@ -36,6 +79,9 @@ static int read_tree_recursive(void *buffer, unsigned long size, buffer = sha1 + 20; size -= len + 20; + if (!match_tree_entry(base, baselen, path, mode, match)) + continue; + if (S_ISDIR(mode)) { int retval; int pathlen = strlen(path); @@ -55,7 +101,8 @@ static int read_tree_recursive(void *buffer, unsigned long size, newbase[baselen + pathlen] = '/'; retval = read_tree_recursive(eltbuf, eltsize, newbase, - baselen + pathlen + 1, stage); + baselen + pathlen + 1, + stage, match); free(eltbuf); free(newbase); if (retval) @@ -68,9 +115,9 @@ static int read_tree_recursive(void *buffer, unsigned long size, return 0; } -int read_tree(void *buffer, unsigned long size, int stage) +int read_tree(void *buffer, unsigned long size, int stage, char **match) { - return read_tree_recursive(buffer, size, "", 0, stage); + return read_tree_recursive(buffer, size, "", 0, stage, match); } struct tree *lookup_tree(const unsigned char *sha1) |