Signed-off-by: Christian Couder <[email protected]>
---
builtin/apply.c | 50 ++++++++++++++++++++++++++++----------------------
1 file changed, 28 insertions(+), 22 deletions(-)
diff --git a/builtin/apply.c b/builtin/apply.c
index 8fda1bd..66ebc9b 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;
@@ -100,6 +114,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;
@@ -3726,52 +3742,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);
}
}
@@ -3785,7 +3791,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)
@@ -3954,7 +3960,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.0.rc1.49.gca61272
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html