Merge branch 'jc/replacing'
authorJunio C Hamano <gitster@pobox.com>
Fri, 20 May 2011 03:37:21 +0000 (20:37 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 May 2011 03:37:21 +0000 (20:37 -0700)
* jc/replacing:
read_sha1_file(): allow selective bypassing of replacement mechanism
inline lookup_replace_object() calls
read_sha1_file(): get rid of read_sha1_file_repl() madness
t6050: make sure we test not just commit replacement
Declare lookup_replace_object() in cache.h, not in commit.h

Conflicts:
environment.c

builtin/mktag.c
cache.h
commit.h
environment.c
object.c
replace_object.c
sha1_file.c
t/t6050-replace.sh
index 324a267163d758b5dea51405265ae89042a657ad..640ab64f418208842ae3901ce37ac8918740037e 100644 (file)
@@ -23,8 +23,8 @@ static int verify_object(const unsigned char *sha1, const char *expected_type)
        int ret = -1;
        enum object_type type;
        unsigned long size;
-       const unsigned char *repl;
-       void *buffer = read_sha1_file_repl(sha1, &type, &size, &repl);
+       void *buffer = read_sha1_file(sha1, &type, &size);
+       const unsigned char *repl = lookup_replace_object(sha1);
 
        if (buffer) {
                if (type == type_from_string(expected_type))
diff --git a/cache.h b/cache.h
index 4ae773647ff5545ecd885d316f77fe6ae8cedad9..66ddfb71b66922e47d95efed4a80df39f1e829da 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -756,13 +756,23 @@ char *strip_path_suffix(const char *path, const char *suffix);
 int daemon_avoid_alias(const char *path);
 int offset_1st_component(const char *path);
 
-/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
-extern int sha1_object_info(const unsigned char *, unsigned long *);
-extern void *read_sha1_file_repl(const unsigned char *sha1, enum object_type *type, unsigned long *size, const unsigned char **replacement);
+/* object replacement */
+#define READ_SHA1_FILE_REPLACE 1
+extern void *read_sha1_file_extended(const unsigned char *sha1, enum object_type *type, unsigned long *size, unsigned flag);
 static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
 {
-       return read_sha1_file_repl(sha1, type, size, NULL);
+       return read_sha1_file_extended(sha1, type, size, READ_SHA1_FILE_REPLACE);
+}
+extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
+static inline const unsigned char *lookup_replace_object(const unsigned char *sha1)
+{
+       if (!read_replace_refs)
+               return sha1;
+       return do_lookup_replace_object(sha1);
 }
+
+/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
+extern int sha1_object_info(const unsigned char *, unsigned long *);
 extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
 extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
 extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
index 43940e2bddcc34d2b74d2ddb76c045939c413c52..3114bd1781c3c5e735dfc1b1a7b4131270992f14 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -145,8 +145,6 @@ struct commit_graft *read_graft_line(char *buf, int len);
 int register_commit_graft(struct commit_graft *, int);
 struct commit_graft *lookup_commit_graft(const unsigned char *sha1);
 
-const unsigned char *lookup_replace_object(const unsigned char *sha1);
-
 extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup);
 extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup);
 extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
index 7fe9f101243d9063ff06fe2c6ea10f220b6a2549..94d58fd24413ec1d1a5769029bd5149b609f0d4e 100644 (file)
@@ -42,7 +42,7 @@ const char *editor_program;
 const char *askpass_program;
 const char *excludes_file;
 enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
-int read_replace_refs = 1;
+int read_replace_refs = 1; /* NEEDSWORK: rename to use_replace_refs */
 enum eol core_eol = EOL_UNSET;
 enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
index 7e1f2bbed2ad7f331fefc78d759acb14050bea48..31976b5d70b6310552b04ce79c7ea0b07bc536d7 100644 (file)
--- a/object.c
+++ b/object.c
@@ -188,8 +188,8 @@ struct object *parse_object(const unsigned char *sha1)
        unsigned long size;
        enum object_type type;
        int eaten;
-       const unsigned char *repl;
-       void *buffer = read_sha1_file_repl(sha1, &type, &size, &repl);
+       const unsigned char *repl = lookup_replace_object(sha1);
+       void *buffer = read_sha1_file(sha1, &type, &size);
 
        if (buffer) {
                struct object *obj;
index 7c6c7544ada4585e62341f0c0854a919f10c2277..d0b1548726e9d2362d27c6947eb61a0647d0eac2 100644 (file)
@@ -85,12 +85,14 @@ static void prepare_replace_object(void)
 
        for_each_replace_ref(register_replace_ref, NULL);
        replace_object_prepared = 1;
+       if (!replace_object_nr)
+               read_replace_refs = 0;
 }
 
 /* We allow "recursive" replacement. Only within reason, though */
 #define MAXREPLACEDEPTH 5
 
-const unsigned char *lookup_replace_object(const unsigned char *sha1)
+const unsigned char *do_lookup_replace_object(const unsigned char *sha1)
 {
        int pos, depth = MAXREPLACEDEPTH;
        const unsigned char *cur = sha1;
index 1a7e41070efa6327859d3c09ede07317cc91ba7d..357f9ab7ff6aad644857986f36fd55da8348744f 100644 (file)
@@ -2205,23 +2205,21 @@ static void *read_object(const unsigned char *sha1, enum object_type *type,
  * deal with them should arrange to call read_object() and give error
  * messages themselves.
  */
-void *read_sha1_file_repl(const unsigned char *sha1,
-                         enum object_type *type,
-                         unsigned long *size,
-                         const unsigned char **replacement)
+void *read_sha1_file_extended(const unsigned char *sha1,
+                             enum object_type *type,
+                             unsigned long *size,
+                             unsigned flag)
 {
-       const unsigned char *repl = lookup_replace_object(sha1);
        void *data;
        char *path;
        const struct packed_git *p;
+       const unsigned char *repl = (flag & READ_SHA1_FILE_REPLACE)
+               ? lookup_replace_object(sha1) : sha1;
 
        errno = 0;
        data = read_object(repl, type, size);
-       if (data) {
-               if (replacement)
-                       *replacement = repl;
+       if (data)
                return data;
-       }
 
        if (errno && errno != ENOENT)
                die_errno("failed to read object %s", sha1_to_hex(sha1));
index ae2194e07d835aa088a1c5b5f5fa5001f41ea7d5..5c87f28e4ed8c8c8dc40fd561516dd8d0db791c9 100755 (executable)
@@ -236,6 +236,20 @@ test_expect_success 'index-pack and replacements' '
        git index-pack test-*.pack
 '
 
-#
-#
+test_expect_success 'not just commits' '
+       echo replaced >file &&
+       git add file &&
+       REPLACED=$(git rev-parse :file) &&
+       mv file file.replaced &&
+
+       echo original >file &&
+       git add file &&
+       ORIGINAL=$(git rev-parse :file) &&
+       git update-ref refs/replace/$ORIGINAL $REPLACED &&
+       mv file file.original &&
+
+       git checkout file &&
+       test_cmp file.replaced file
+'
+
 test_done