[PATCH] Rename and extend read_tree_with_tree_or_commit_sha1
This patch renames read_tree_with_tree_or_commit_sha1() to read_object_with_reference() and extends it to automatically dereference not just "commit" objects but "tag" objects. With this patch, you can say e.g.: ls-tree $tag read-tree -m $(merge-base $tag $HEAD) $tag $HEAD diff-cache $tag diff-tree $tag $HEAD Signed-off-by: Junio C Hamano <junkio@cox.net> Signed-off-by: Linus Torvalds <torvalds@osdl.org>maint
parent
cf9a113d35
commit
40469ee9c6
5
cache.h
5
cache.h
|
@ -143,9 +143,10 @@ extern int error(const char *err, ...);
|
||||||
|
|
||||||
extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
|
extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
|
||||||
|
|
||||||
extern void *read_tree_with_tree_or_commit_sha1(const unsigned char *sha1,
|
extern void *read_object_with_reference(const unsigned char *sha1,
|
||||||
|
const unsigned char *required_type,
|
||||||
unsigned long *size,
|
unsigned long *size,
|
||||||
unsigned char *tree_sha1_ret);
|
unsigned char *sha1_ret);
|
||||||
|
|
||||||
static inline void *xmalloc(int size)
|
static inline void *xmalloc(int size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -180,7 +180,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
mark_merge_entries();
|
mark_merge_entries();
|
||||||
|
|
||||||
tree = read_tree_with_tree_or_commit_sha1(tree_sha1, &size, 0);
|
tree = read_object_with_reference(tree_sha1, "tree", &size, 0);
|
||||||
if (!tree)
|
if (!tree)
|
||||||
die("bad tree object %s", argv[1]);
|
die("bad tree object %s", argv[1]);
|
||||||
if (read_tree(tree, size, 1))
|
if (read_tree(tree, size, 1))
|
||||||
|
|
|
@ -238,10 +238,10 @@ static int diff_tree_sha1(const unsigned char *old, const unsigned char *new, co
|
||||||
unsigned long size1, size2;
|
unsigned long size1, size2;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
tree1 = read_tree_with_tree_or_commit_sha1(old, &size1, 0);
|
tree1 = read_object_with_reference(old, "tree", &size1, 0);
|
||||||
if (!tree1)
|
if (!tree1)
|
||||||
die("unable to read source tree (%s)", sha1_to_hex(old));
|
die("unable to read source tree (%s)", sha1_to_hex(old));
|
||||||
tree2 = read_tree_with_tree_or_commit_sha1(new, &size2, 0);
|
tree2 = read_object_with_reference(new, "tree", &size2, 0);
|
||||||
if (!tree2)
|
if (!tree2)
|
||||||
die("unable to read destination tree (%s)", sha1_to_hex(new));
|
die("unable to read destination tree (%s)", sha1_to_hex(new));
|
||||||
retval = diff_tree(tree1, size1, tree2, size2, base);
|
retval = diff_tree(tree1, size1, tree2, size2, base);
|
||||||
|
|
|
@ -114,7 +114,7 @@ int main(int argc, char **argv)
|
||||||
// Read the signature
|
// Read the signature
|
||||||
size = read(0, buffer, MAXSIZE);
|
size = read(0, buffer, MAXSIZE);
|
||||||
|
|
||||||
// Verify it for some basic sanity: it needs to start with "object <sha1>\ntag "
|
// Verify it for some basic sanity: it needs to start with "object <sha1>\ntype "
|
||||||
if (verify_tag(buffer, size) < 0)
|
if (verify_tag(buffer, size) < 0)
|
||||||
die("invalid tag signature file");
|
die("invalid tag signature file");
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ static int list(unsigned char *sha1)
|
||||||
void *buffer;
|
void *buffer;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
|
||||||
buffer = read_tree_with_tree_or_commit_sha1(sha1, &size, 0);
|
buffer = read_object_with_reference(sha1, "tree", &size, 0);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
die("unable to read sha1 file");
|
die("unable to read sha1 file");
|
||||||
list_recursive(buffer, "tree", size, NULL);
|
list_recursive(buffer, "tree", size, NULL);
|
||||||
|
|
|
@ -12,7 +12,7 @@ static int unpack_tree(unsigned char *sha1)
|
||||||
void *buffer;
|
void *buffer;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
|
||||||
buffer = read_tree_with_tree_or_commit_sha1(sha1, &size, 0);
|
buffer = read_object_with_reference(sha1, "tree", &size, 0);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return -1;
|
return -1;
|
||||||
return read_tree(buffer, size, stage);
|
return read_tree(buffer, size, stage);
|
||||||
|
|
57
sha1_file.c
57
sha1_file.c
|
@ -189,44 +189,49 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *read_tree_with_tree_or_commit_sha1(const unsigned char *sha1,
|
void *read_object_with_reference(const unsigned char *sha1,
|
||||||
|
const unsigned char *required_type,
|
||||||
unsigned long *size,
|
unsigned long *size,
|
||||||
unsigned char *tree_sha1_return)
|
unsigned char *actual_sha1_return)
|
||||||
{
|
{
|
||||||
char type[20];
|
char type[20];
|
||||||
void *buffer;
|
void *buffer;
|
||||||
unsigned long isize;
|
unsigned long isize;
|
||||||
int was_commit = 0;
|
unsigned char actual_sha1[20];
|
||||||
unsigned char tree_sha1[20];
|
|
||||||
|
|
||||||
buffer = read_sha1_file(sha1, type, &isize);
|
memcpy(actual_sha1, sha1, 20);
|
||||||
|
while (1) {
|
||||||
|
int ref_length = -1;
|
||||||
|
const char *ref_type = NULL;
|
||||||
|
|
||||||
/*
|
buffer = read_sha1_file(actual_sha1, type, &isize);
|
||||||
* We might have read a commit instead of a tree, in which case
|
if (!buffer)
|
||||||
* we parse out the tree_sha1 and attempt to read from there.
|
return NULL;
|
||||||
* (buffer + 5) is because the tree sha1 is always at offset 5
|
if (!strcmp(type, required_type)) {
|
||||||
* in a commit record ("tree ").
|
*size = isize;
|
||||||
*/
|
if (actual_sha1_return)
|
||||||
if (buffer &&
|
memcpy(actual_sha1_return, actual_sha1, 20);
|
||||||
!strcmp(type, "commit") &&
|
return buffer;
|
||||||
!get_sha1_hex(buffer + 5, tree_sha1)) {
|
|
||||||
free(buffer);
|
|
||||||
buffer = read_sha1_file(tree_sha1, type, &isize);
|
|
||||||
was_commit = 1;
|
|
||||||
}
|
}
|
||||||
|
/* Handle references */
|
||||||
/*
|
else if (!strcmp(type, "commit"))
|
||||||
* Now do we have something and if so is it a tree?
|
ref_type = "tree ";
|
||||||
*/
|
else if (!strcmp(type, "tag"))
|
||||||
if (!buffer || strcmp(type, "tree")) {
|
ref_type = "object ";
|
||||||
|
else {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
ref_length = strlen(ref_type);
|
||||||
|
|
||||||
*size = isize;
|
if (memcmp(buffer, ref_type, ref_length) ||
|
||||||
if (tree_sha1_return)
|
get_sha1_hex(buffer + ref_length, actual_sha1)) {
|
||||||
memcpy(tree_sha1_return, was_commit ? tree_sha1 : sha1, 20);
|
free(buffer);
|
||||||
return buffer;
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Now we have the ID of the referred-to object in
|
||||||
|
* actual_sha1. Check again. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned char *returnsha1)
|
int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned char *returnsha1)
|
||||||
|
|
Loading…
Reference in New Issue