mirror of
https://github.com/git/git.git
synced 2026-01-10 10:13:33 +00:00
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.
This commit is contained in:
2
cache.h
2
cache.h
@@ -191,7 +191,7 @@ extern char *write_sha1_file_prepare(void *buf,
|
|||||||
extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
|
extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
|
||||||
|
|
||||||
/* Read a tree into the cache */
|
/* Read a tree into the cache */
|
||||||
extern int read_tree(void *buffer, unsigned long size, int stage);
|
extern int read_tree(void *buffer, unsigned long size, int stage, char **paths);
|
||||||
|
|
||||||
extern int write_sha1_from_fd(const unsigned char *sha1, int fd);
|
extern int write_sha1_from_fd(const unsigned char *sha1, int fd);
|
||||||
extern int write_sha1_to_fd(int fd, const unsigned char *sha1);
|
extern int write_sha1_to_fd(int fd, const unsigned char *sha1);
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ int main(int argc, const char **argv)
|
|||||||
tree = read_object_with_reference(sha1, "tree", &size, NULL);
|
tree = read_object_with_reference(sha1, "tree", &size, NULL);
|
||||||
if (!tree)
|
if (!tree)
|
||||||
die("bad tree object %s", tree_name);
|
die("bad tree object %s", tree_name);
|
||||||
if (read_tree(tree, size, 1))
|
if (read_tree(tree, size, 1, NULL))
|
||||||
die("unable to read tree object %s", tree_name);
|
die("unable to read tree object %s", tree_name);
|
||||||
|
|
||||||
ret = diff_cache(active_cache, active_nr);
|
ret = diff_cache(active_cache, active_nr);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ static int unpack_tree(unsigned char *sha1)
|
|||||||
buffer = read_object_with_reference(sha1, "tree", &size, NULL);
|
buffer = read_object_with_reference(sha1, "tree", &size, NULL);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return -1;
|
return -1;
|
||||||
ret = read_tree(buffer, size, stage);
|
ret = read_tree(buffer, size, stage, NULL);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
55
tree.c
55
tree.c
@@ -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);
|
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,
|
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) {
|
while (size) {
|
||||||
int len = strlen(buffer)+1;
|
int len = strlen(buffer)+1;
|
||||||
@@ -36,6 +79,9 @@ static int read_tree_recursive(void *buffer, unsigned long size,
|
|||||||
buffer = sha1 + 20;
|
buffer = sha1 + 20;
|
||||||
size -= len + 20;
|
size -= len + 20;
|
||||||
|
|
||||||
|
if (!match_tree_entry(base, baselen, path, mode, match))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (S_ISDIR(mode)) {
|
if (S_ISDIR(mode)) {
|
||||||
int retval;
|
int retval;
|
||||||
int pathlen = strlen(path);
|
int pathlen = strlen(path);
|
||||||
@@ -55,7 +101,8 @@ static int read_tree_recursive(void *buffer, unsigned long size,
|
|||||||
newbase[baselen + pathlen] = '/';
|
newbase[baselen + pathlen] = '/';
|
||||||
retval = read_tree_recursive(eltbuf, eltsize,
|
retval = read_tree_recursive(eltbuf, eltsize,
|
||||||
newbase,
|
newbase,
|
||||||
baselen + pathlen + 1, stage);
|
baselen + pathlen + 1,
|
||||||
|
stage, match);
|
||||||
free(eltbuf);
|
free(eltbuf);
|
||||||
free(newbase);
|
free(newbase);
|
||||||
if (retval)
|
if (retval)
|
||||||
@@ -68,9 +115,9 @@ static int read_tree_recursive(void *buffer, unsigned long size,
|
|||||||
return 0;
|
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)
|
struct tree *lookup_tree(const unsigned char *sha1)
|
||||||
|
|||||||
Reference in New Issue
Block a user