git-p4: additional testing of --changes-block-size
[gitweb.git] / sha1_name.c
index 10969435bbaba89f4169d4ae9278a0203c5bcff8..e57513e61032fb851a669255c30d8417f66c81f9 100644 (file)
@@ -6,6 +6,7 @@
 #include "tree-walk.h"
 #include "refs.h"
 #include "remote.h"
+#include "dir.h"
 
 static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);
 
@@ -844,11 +845,11 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l
 /* Remember to update object flag allocation in object.h */
 #define ONELINE_SEEN (1u<<20)
 
-static int handle_one_ref(const char *path,
-               const unsigned char *sha1, int flag, void *cb_data)
+static int handle_one_ref(const char *path, const struct object_id *oid,
+                         int flag, void *cb_data)
 {
        struct commit_list **list = cb_data;
-       struct object *object = parse_object(sha1);
+       struct object *object = parse_object(oid->hash);
        if (!object)
                return 0;
        if (object->type == OBJ_TAG) {
@@ -1246,14 +1247,13 @@ static void diagnose_invalid_sha1_path(const char *prefix,
                                       const char *object_name,
                                       int object_name_len)
 {
-       struct stat st;
        unsigned char sha1[20];
        unsigned mode;
 
        if (!prefix)
                prefix = "";
 
-       if (!lstat(filename, &st))
+       if (file_exists(filename))
                die("Path '%s' exists on disk, but not in '%.*s'.",
                    filename, object_name_len, object_name);
        if (errno == ENOENT || errno == ENOTDIR) {
@@ -1280,7 +1280,6 @@ static void diagnose_invalid_index_path(int stage,
                                        const char *prefix,
                                        const char *filename)
 {
-       struct stat st;
        const struct cache_entry *ce;
        int pos;
        unsigned namelen = strlen(filename);
@@ -1323,7 +1322,7 @@ static void diagnose_invalid_index_path(int stage,
                            ce_stage(ce), filename);
        }
 
-       if (!lstat(filename, &st))
+       if (file_exists(filename))
                die("Path '%s' exists on disk, but not in the index.", filename);
        if (errno == ENOENT || errno == ENOTDIR)
                die("Path '%s' does not exist (neither on disk nor in the index).",
@@ -1380,6 +1379,7 @@ static int get_sha1_with_context_1(const char *name,
                int pos;
                if (!only_to_die && namelen > 2 && name[1] == '/') {
                        struct commit_list *list = NULL;
+
                        for_each_ref(handle_one_ref, &list);
                        commit_list_sort_by_date(&list);
                        return get_sha1_oneline(name + 2, sha1, list);
@@ -1443,11 +1443,19 @@ static int get_sha1_with_context_1(const char *name,
                        new_filename = resolve_relative_path(filename);
                        if (new_filename)
                                filename = new_filename;
-                       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);
+                       if (flags & GET_SHA1_FOLLOW_SYMLINKS) {
+                               ret = get_tree_entry_follow_symlinks(tree_sha1,
+                                       filename, sha1, &oc->symlink_path,
+                                       &oc->mode);
+                       } 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);
                        strlcpy(oc->path, filename, sizeof(oc->path));
@@ -1478,5 +1486,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)
 {
+       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);
 }