Signed-off-by: Christian Couder <chrisc...@tuxfamily.org>
---
 builtin/apply.c | 50 ++++++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index b4c2bd8..8508607 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -34,6 +34,20 @@ enum ws_ignore {
        ignore_ws_change
 };
 
+/*
+ * We need to keep track of how symlinks in the preimage are
+ * manipulated by the patches.  A patch to add a/b/c where a/b
+ * is a symlink should not be allowed to affect the directory
+ * the symlink points at, but if the same patch removes a/b,
+ * it is perfectly fine, as the patch removes a/b to make room
+ * to create a directory a/b so that a/b/c can be created.
+ *
+ * See also "struct string_list symlink_changes" in "struct
+ * apply_state".
+ */
+#define SYMLINK_GOES_AWAY 01
+#define SYMLINK_IN_RESULT 02
+
 struct apply_state {
        const char *prefix;
        int prefix_length;
@@ -99,6 +113,8 @@ struct apply_state {
         */
        struct string_list fn_table;
 
+       struct string_list symlink_changes;
+
        int p_value;
        int p_value_known;
        unsigned int p_context;
@@ -3723,52 +3739,42 @@ static int check_to_create(struct apply_state *state,
        return 0;
 }
 
-/*
- * We need to keep track of how symlinks in the preimage are
- * manipulated by the patches.  A patch to add a/b/c where a/b
- * is a symlink should not be allowed to affect the directory
- * the symlink points at, but if the same patch removes a/b,
- * it is perfectly fine, as the patch removes a/b to make room
- * to create a directory a/b so that a/b/c can be created.
- */
-static struct string_list symlink_changes;
-#define SYMLINK_GOES_AWAY 01
-#define SYMLINK_IN_RESULT 02
-
-static uintptr_t register_symlink_changes(const char *path, uintptr_t what)
+static uintptr_t register_symlink_changes(struct apply_state *state,
+                                         const char *path,
+                                         uintptr_t what)
 {
        struct string_list_item *ent;
 
-       ent = string_list_lookup(&symlink_changes, path);
+       ent = string_list_lookup(&state->symlink_changes, path);
        if (!ent) {
-               ent = string_list_insert(&symlink_changes, path);
+               ent = string_list_insert(&state->symlink_changes, path);
                ent->util = (void *)0;
        }
        ent->util = (void *)(what | ((uintptr_t)ent->util));
        return (uintptr_t)ent->util;
 }
 
-static uintptr_t check_symlink_changes(const char *path)
+static uintptr_t check_symlink_changes(struct apply_state *state, const char 
*path)
 {
        struct string_list_item *ent;
 
-       ent = string_list_lookup(&symlink_changes, path);
+       ent = string_list_lookup(&state->symlink_changes, path);
        if (!ent)
                return 0;
        return (uintptr_t)ent->util;
 }
 
-static void prepare_symlink_changes(struct patch *patch)
+static void prepare_symlink_changes(struct apply_state *state, struct patch 
*patch)
 {
        for ( ; patch; patch = patch->next) {
                if ((patch->old_name && S_ISLNK(patch->old_mode)) &&
                    (patch->is_rename || patch->is_delete))
                        /* the symlink at patch->old_name is removed */
-                       register_symlink_changes(patch->old_name, 
SYMLINK_GOES_AWAY);
+                       register_symlink_changes(state, patch->old_name, 
SYMLINK_GOES_AWAY);
 
                if (patch->new_name && S_ISLNK(patch->new_mode))
                        /* the symlink at patch->new_name is created or remains 
*/
-                       register_symlink_changes(patch->new_name, 
SYMLINK_IN_RESULT);
+                       register_symlink_changes(state, patch->new_name, 
SYMLINK_IN_RESULT);
        }
 }
 
@@ -3782,7 +3788,7 @@ static int path_is_beyond_symlink_1(struct apply_state 
*state, struct strbuf *na
                if (!name->len)
                        break;
                name->buf[name->len] = '\0';
-               change = check_symlink_changes(name->buf);
+               change = check_symlink_changes(state, name->buf);
                if (change & SYMLINK_IN_RESULT)
                        return 1;
                if (change & SYMLINK_GOES_AWAY)
@@ -3951,7 +3957,7 @@ static int check_patch_list(struct apply_state *state, 
struct patch *patch)
 {
        int err = 0;
 
-       prepare_symlink_changes(patch);
+       prepare_symlink_changes(state, patch);
        prepare_fn_table(state, patch);
        while (patch) {
                if (state->apply_verbosely)
-- 
2.8.1.300.g5fed0c0

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to