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>
This commit is contained in:
David Turner 2015-05-20 13:03:39 -04:00 коммит произвёл Junio C Hamano
Родитель 275721c267
Коммит c4ec96774b
2 изменённых файлов: 28 добавлений и 12 удалений

20
cache.h
Просмотреть файл

@ -952,15 +952,21 @@ struct object_context {
unsigned char tree[20]; unsigned char tree[20];
char path[PATH_MAX]; char path[PATH_MAX];
unsigned mode; unsigned mode;
/*
* symlink_path is only used by get_tree_entry_follow_symlinks,
* and only for symlinks that point outside the repository.
*/
struct strbuf symlink_path;
}; };
#define GET_SHA1_QUIETLY 01 #define GET_SHA1_QUIETLY 01
#define GET_SHA1_COMMIT 02 #define GET_SHA1_COMMIT 02
#define GET_SHA1_COMMITTISH 04 #define GET_SHA1_COMMITTISH 04
#define GET_SHA1_TREE 010 #define GET_SHA1_TREE 010
#define GET_SHA1_TREEISH 020 #define GET_SHA1_TREEISH 020
#define GET_SHA1_BLOB 040 #define GET_SHA1_BLOB 040
#define GET_SHA1_ONLY_TO_DIE 04000 #define GET_SHA1_FOLLOW_SYMLINKS 0100
#define GET_SHA1_ONLY_TO_DIE 04000
extern int get_sha1(const char *str, unsigned char *sha1); extern int get_sha1(const char *str, unsigned char *sha1);
extern int get_sha1_commit(const char *str, unsigned char *sha1); extern int get_sha1_commit(const char *str, unsigned char *sha1);

Просмотреть файл

@ -1434,11 +1434,19 @@ static int get_sha1_with_context_1(const char *name,
new_filename = resolve_relative_path(filename); new_filename = resolve_relative_path(filename);
if (new_filename) if (new_filename)
filename = new_filename; filename = new_filename;
ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode); if (flags & GET_SHA1_FOLLOW_SYMLINKS) {
if (ret && only_to_die) { ret = get_tree_entry_follow_symlinks(tree_sha1,
diagnose_invalid_sha1_path(prefix, filename, filename, sha1, &oc->symlink_path,
tree_sha1, &oc->mode);
name, len); } else {
ret = get_tree_entry(tree_sha1, filename,
sha1, &oc->mode);
if (ret && only_to_die) {
diagnose_invalid_sha1_path(prefix,
filename,
tree_sha1,
name, len);
}
} }
hashcpy(oc->tree, tree_sha1); hashcpy(oc->tree, tree_sha1);
strlcpy(oc->path, filename, sizeof(oc->path)); strlcpy(oc->path, filename, sizeof(oc->path));
@ -1469,5 +1477,7 @@ void maybe_die_on_misspelt_object_name(const char *name, const char *prefix)
int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc) int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc)
{ {
if (flags & GET_SHA1_FOLLOW_SYMLINKS && flags & GET_SHA1_ONLY_TO_DIE)
die("BUG: incompatible flags for get_sha1_with_context");
return get_sha1_with_context_1(str, flags, NULL, sha1, orc); return get_sha1_with_context_1(str, flags, NULL, sha1, orc);
} }