sha1_name: get_sha1_with_context learns to follow symlinks

Wire up get_sha1_with_context to call get_tree_entry_follow_symlinks when GET_SHA1_FOLLOW_SYMLINKS is passed in flags. G_S_FOLLOW_SYMLINKS is incompatible with G_S_ONLY_TO_DIE because the diagnosis that ONLY_TO_DIE triggers does not at present consider symlinks, and it would be a significant amount of additional code to allow it to do so. Signed-off-by: David Turner <dturner@twopensource.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

David Turner committed May 20, 2015 at 13:03 UTC c4ec96774ba247597bc4c571d85069d225665422
2 files changed +28 -12
cache.h
+13 -7
@@ -952,15 +952,21 @@ struct object_context {
952 unsigned char tree[20];
953 char path[PATH_MAX];
954 unsigned mode;
955 + /*
956 + * symlink_path is only used by get_tree_entry_follow_symlinks,
957 + * and only for symlinks that point outside the repository.
958 + */
959 + struct strbuf symlink_path;
960 };
961
957 -#define GET_SHA1_QUIETLY 01
958 -#define GET_SHA1_COMMIT 02
959 -#define GET_SHA1_COMMITTISH 04
960 -#define GET_SHA1_TREE 010
961 -#define GET_SHA1_TREEISH 020
962 -#define GET_SHA1_BLOB 040
963 -#define GET_SHA1_ONLY_TO_DIE 04000
962 +#define GET_SHA1_QUIETLY 01
963 +#define GET_SHA1_COMMIT 02
964 +#define GET_SHA1_COMMITTISH 04
965 +#define GET_SHA1_TREE 010
966 +#define GET_SHA1_TREEISH 020
967 +#define GET_SHA1_BLOB 040
968 +#define GET_SHA1_FOLLOW_SYMLINKS 0100
969 +#define GET_SHA1_ONLY_TO_DIE 04000
970
971 extern int get_sha1(const char *str, unsigned char *sha1);
972 extern int get_sha1_commit(const char *str, unsigned char *sha1);
sha1_name.c
+15 -5
@@ -1434,11 +1434,19 @@ static int get_sha1_with_context_1(const char *name,
1434 new_filename = resolve_relative_path(filename);
1435 if (new_filename)
1436 filename = new_filename;
1437 - ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode);
1438 - if (ret && only_to_die) {
1439 - diagnose_invalid_sha1_path(prefix, filename,
1440 - tree_sha1,
1441 - name, len);
1437 + if (flags & GET_SHA1_FOLLOW_SYMLINKS) {
1438 + ret = get_tree_entry_follow_symlinks(tree_sha1,
1439 + filename, sha1, &oc->symlink_path,
1440 + &oc->mode);
1441 + } else {
1442 + ret = get_tree_entry(tree_sha1, filename,
1443 + sha1, &oc->mode);
1444 + if (ret && only_to_die) {
1445 + diagnose_invalid_sha1_path(prefix,
1446 + filename,
1447 + tree_sha1,
1448 + name, len);
1449 + }
1450 }
1451 hashcpy(oc->tree, tree_sha1);
1452 strlcpy(oc->path, filename, sizeof(oc->path));
@@ -1469,5 +1477,7 @@ void maybe_die_on_misspelt_object_name(const char *name, const char *prefix)
1477
1478 int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc)
1479 {
1480 + if (flags & GET_SHA1_FOLLOW_SYMLINKS && flags & GET_SHA1_ONLY_TO_DIE)
1481 + die("BUG: incompatible flags for get_sha1_with_context");
1482 return get_sha1_with_context_1(str, flags, NULL, sha1, orc);
1483 }