mirror of
https://github.com/git/git.git
synced 2024-11-24 10:26:17 +08:00
[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>
This commit is contained in:
parent
cf9a113d35
commit
40469ee9c6
7
cache.h
7
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 void *read_tree_with_tree_or_commit_sha1(const unsigned char *sha1,
|
||||
unsigned long *size,
|
||||
unsigned char *tree_sha1_ret);
|
||||
extern void *read_object_with_reference(const unsigned char *sha1,
|
||||
const unsigned char *required_type,
|
||||
unsigned long *size,
|
||||
unsigned char *sha1_ret);
|
||||
|
||||
static inline void *xmalloc(int size)
|
||||
{
|
||||
|
@ -180,7 +180,7 @@ int main(int argc, char **argv)
|
||||
|
||||
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)
|
||||
die("bad tree object %s", argv[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;
|
||||
int retval;
|
||||
|
||||
tree1 = read_tree_with_tree_or_commit_sha1(old, &size1, 0);
|
||||
tree1 = read_object_with_reference(old, "tree", &size1, 0);
|
||||
if (!tree1)
|
||||
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)
|
||||
die("unable to read destination tree (%s)", sha1_to_hex(new));
|
||||
retval = diff_tree(tree1, size1, tree2, size2, base);
|
||||
|
@ -114,7 +114,7 @@ int main(int argc, char **argv)
|
||||
// Read the signature
|
||||
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)
|
||||
die("invalid tag signature file");
|
||||
|
||||
|
@ -73,7 +73,7 @@ static int list(unsigned char *sha1)
|
||||
void *buffer;
|
||||
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)
|
||||
die("unable to read sha1 file");
|
||||
list_recursive(buffer, "tree", size, NULL);
|
||||
|
@ -12,7 +12,7 @@ static int unpack_tree(unsigned char *sha1)
|
||||
void *buffer;
|
||||
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)
|
||||
return -1;
|
||||
return read_tree(buffer, size, stage);
|
||||
|
67
sha1_file.c
67
sha1_file.c
@ -189,44 +189,49 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *read_tree_with_tree_or_commit_sha1(const unsigned char *sha1,
|
||||
unsigned long *size,
|
||||
unsigned char *tree_sha1_return)
|
||||
void *read_object_with_reference(const unsigned char *sha1,
|
||||
const unsigned char *required_type,
|
||||
unsigned long *size,
|
||||
unsigned char *actual_sha1_return)
|
||||
{
|
||||
char type[20];
|
||||
void *buffer;
|
||||
unsigned long isize;
|
||||
int was_commit = 0;
|
||||
unsigned char tree_sha1[20];
|
||||
unsigned char actual_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;
|
||||
|
||||
/*
|
||||
* We might have read a commit instead of a tree, in which case
|
||||
* we parse out the tree_sha1 and attempt to read from there.
|
||||
* (buffer + 5) is because the tree sha1 is always at offset 5
|
||||
* in a commit record ("tree ").
|
||||
*/
|
||||
if (buffer &&
|
||||
!strcmp(type, "commit") &&
|
||||
!get_sha1_hex(buffer + 5, tree_sha1)) {
|
||||
free(buffer);
|
||||
buffer = read_sha1_file(tree_sha1, type, &isize);
|
||||
was_commit = 1;
|
||||
buffer = read_sha1_file(actual_sha1, type, &isize);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
if (!strcmp(type, required_type)) {
|
||||
*size = isize;
|
||||
if (actual_sha1_return)
|
||||
memcpy(actual_sha1_return, actual_sha1, 20);
|
||||
return buffer;
|
||||
}
|
||||
/* Handle references */
|
||||
else if (!strcmp(type, "commit"))
|
||||
ref_type = "tree ";
|
||||
else if (!strcmp(type, "tag"))
|
||||
ref_type = "object ";
|
||||
else {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
ref_length = strlen(ref_type);
|
||||
|
||||
if (memcmp(buffer, ref_type, ref_length) ||
|
||||
get_sha1_hex(buffer + ref_length, actual_sha1)) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
/* Now we have the ID of the referred-to object in
|
||||
* actual_sha1. Check again. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Now do we have something and if so is it a tree?
|
||||
*/
|
||||
if (!buffer || strcmp(type, "tree")) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*size = isize;
|
||||
if (tree_sha1_return)
|
||||
memcpy(tree_sha1_return, was_commit ? tree_sha1 : sha1, 20);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned char *returnsha1)
|
||||
|
Loading…
Reference in New Issue
Block a user