Browse Source

[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
Junio C Hamano 20 years ago committed by Linus Torvalds
parent
commit
40469ee9c6
  1. 7
      cache.h
  2. 2
      diff-cache.c
  3. 4
      diff-tree.c
  4. 2
      git-mktag.c
  5. 2
      ls-tree.c
  6. 2
      read-tree.c
  7. 69
      sha1_file.c

7
cache.h

@ -143,9 +143,10 @@ extern int error(const char *err, ...); @@ -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)
{

2
diff-cache.c

@ -180,7 +180,7 @@ int main(int argc, char **argv) @@ -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))

4
diff-tree.c

@ -238,10 +238,10 @@ static int diff_tree_sha1(const unsigned char *old, const unsigned char *new, co @@ -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);

2
git-mktag.c

@ -114,7 +114,7 @@ int main(int argc, char **argv) @@ -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");


2
ls-tree.c

@ -73,7 +73,7 @@ static int list(unsigned char *sha1) @@ -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);

2
read-tree.c

@ -12,7 +12,7 @@ static int unpack_tree(unsigned char *sha1) @@ -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);

69
sha1_file.c

@ -189,44 +189,49 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size @@ -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];

buffer = read_sha1_file(sha1, type, &isize);

/*
* 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;
}
unsigned char actual_sha1[20];

/*
* Now do we have something and if so is it a tree?
*/
if (!buffer || strcmp(type, "tree")) {
free(buffer);
return NULL;
}
memcpy(actual_sha1, sha1, 20);
while (1) {
int ref_length = -1;
const char *ref_type = NULL;

*size = isize;
if (tree_sha1_return)
memcpy(tree_sha1_return, was_commit ? tree_sha1 : sha1, 20);
return buffer;
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. */
}
}

int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned char *returnsha1)

Loading…
Cancel
Save