{"thread":{"id":"41649","subject":"[RFC/PATCH 00/48] Libifying git apply","startedAt":"2016-03-09T17:48:28Z","lastAt":"2016-03-11T17:34:50Z","messageCount":58,"participants":["Christian Couder","Junio C Hamano","Stefan Beller","Duy Nguyen"],"isPatch":true,"patchVersion":1,"patchTotal":48},"messages":[{"id":"280423","messageId":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":null,"subject":"[RFC/PATCH 00/48] Libifying git apply","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:28Z","receivedAt":"2016-03-09T17:48:28Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This is a patch series about libifying \"git apply\" functionality, to\nbe able to use this functionality in \"git am\" without spawning new\nprocesses. This should make \"git am\" and \"git rebase\" significantly\nfaster.\n\nThis has been discussed in the following thread:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/287236/\n\nThis RFC patch series for now just gets rid of the global variables\nand refactors the code around a bit.\n\nAs suggested by Junio the global variables in builtin/apply.c are just\nthrown into a single \"apply_state\" structure that is passed around the\ncallchain. A new parameter called \"state\" that is a pointer to the\n\"apply_state\" structure comes at the beginning of the helper functions\nthat need it.\n\nBefore I make further changes to handle erroneous input and make the\nlibified functions not die() and properly clean things up, I'd be\nhappy to get some feedback.\n\nOne point I'd especially welcome feedback about is the fact that there\nare many boolean options that are using OPT_BOOL(...), so they use an\nint. And there are a few others that are using OPT_BIT(...), so they\nuse just a bit. I wonder if it is worth it to try to be consistent,\nand maybe also to try to save some memory.\n\nRelated to this, some of the variables for these options have not been\nmoved into the \"apply_state\" structure, because they are not global to\nthe file, but maybe for consistency they should be.\n\nChristian Couder (48):\n  builtin/apply: avoid parameter shadowing 'p_value' global\n  builtin/apply: avoid parameter shadowing 'linenr' global\n  builtin/apply: avoid local variable shadowing 'len' parameter\n  builtin/apply: extract line_by_line_fuzzy_match() from\n    match_fragment()\n  builtin/apply: move 'options' variable into cmd_apply()\n  builtin/apply: introduce 'struct apply_state' to start libifying\n  builtin/apply: move 'newfd' global into 'struct apply_state'\n  builtin/apply: move 'unidiff_zero' global into 'struct apply_state'\n  builtin/apply: move 'check' global into 'struct apply_state'\n  builtin/apply: move 'check_index' global into 'struct apply_state'\n  builtin/apply: move 'apply_in_reverse' global into 'struct\n    apply_state'\n  builtin/apply: move 'apply_with_reject' global into 'struct\n    apply_state'\n  builtin/apply: move 'apply_verbosely' global into 'struct apply_state'\n  builtin/apply: move 'update_index' global into 'struct apply_state'\n  builtin/apply: move 'allow_overlap' global into 'struct apply_state'\n  builtin/apply: move 'cached' global into 'struct apply_state'\n  builtin/apply: move 'diffstat' global into 'struct apply_state'\n  builtin/apply: move 'numstat' global into 'struct apply_state'\n  builtin/apply: move 'summary' global into 'struct apply_state'\n  builtin/apply: move 'threeway' global into 'struct apply_state'\n  builtin/apply: move 'no-add' global into 'struct apply_state'\n  builtin/apply: move 'unsafe_paths' global into 'struct apply_state'\n  builtin/apply: move 'line_termination' global into 'struct\n    apply_state'\n  builtin/apply: move 'fake_ancestor' global into 'struct apply_state'\n  builtin/apply: move 'p_context' global into 'struct apply_state'\n  builtin/apply: move 'apply' global into 'struct apply_state'\n  builtin/apply: move 'read_stdin' global into cmd_apply()\n  builtin/apply: move 'lock_file' global into 'struct apply_state'\n  builtin/apply: move 'patch_input_file' global into 'struct\n    apply_state'\n  builtin/apply: move 'limit_by_name' global into 'struct apply_state'\n  builtin/apply: move 'has_include' global into 'struct apply_state'\n  builtin/apply: move 'p_value' global into 'struct apply_state'\n  builtin/apply: move 'p_value_known' global into 'struct apply_state'\n  builtin/apply: move 'root' global into 'struct apply_state'\n  builtin/apply: move 'whitespace_error' global into 'struct\n    apply_state'\n  builtin/apply: move 'whitespace_option' into 'struct apply_state'\n  builtin/apply: remove whitespace_option arg from\n    set_default_whitespace_mode()\n  builtin/apply: move 'squelch_whitespace_errors' into 'struct\n    apply_state'\n  builtin/apply: move 'applied_after_fixing_ws' into 'struct\n    apply_state'\n  builtin/apply: move 'ws_error_action' into 'struct apply_state'\n  builtin/apply: move 'ws_ignore_action' into 'struct apply_state'\n  builtin/apply: move 'max_change' and 'max_len' into 'struct\n    apply_state'\n  builtin/apply: move 'linenr' global into 'struct apply_state'\n  builtin/apply: move 'fn_table' global into 'struct apply_state'\n  builtin/apply: move 'symlink_changes' global into 'struct apply_state'\n  builtin/apply: move 'state' init into init_apply_state()\n  builtin/apply: move 'state' check into check_apply_state()\n  builtin/apply: move applying patches into apply_all_patches()\n\n builtin/apply.c | 1424 +++++++++++++++++++++++++++++++------------------------\n 1 file changed, 817 insertions(+), 607 deletions(-)\n\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280424","messageId":"1457545756-20616-2-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 01/48] builtin/apply: avoid parameter shadowing 'p_value' global","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:29Z","receivedAt":"2016-03-09T17:48:29Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 24 ++++++++++++------------\n 1 file changed, 12 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 42c610e..7d9be63 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -469,7 +469,7 @@ static char *squash_slash(char *name)\n \treturn name;\n }\n \n-static char *find_name_gnu(const char *line, const char *def, int p_value)\n+static char *find_name_gnu(const char *line, const char *def, int p_v)\n {\n \tstruct strbuf name = STRBUF_INIT;\n \tchar *cp;\n@@ -483,7 +483,7 @@ static char *find_name_gnu(const char *line, const char *def, int p_value)\n \t\treturn NULL;\n \t}\n \n-\tfor (cp = name.buf; p_value; p_value--) {\n+\tfor (cp = name.buf; p_v; p_v--) {\n \t\tcp = strchr(cp, '/');\n \t\tif (!cp) {\n \t\t\tstrbuf_release(&name);\n@@ -658,12 +658,12 @@ static size_t diff_timestamp_len(const char *line, size_t len)\n }\n \n static char *find_name_common(const char *line, const char *def,\n-\t\t\t      int p_value, const char *end, int terminate)\n+\t\t\t      int p_v, const char *end, int terminate)\n {\n \tint len;\n \tconst char *start = NULL;\n \n-\tif (p_value == 0)\n+\tif (p_v == 0)\n \t\tstart = line;\n \twhile (line != end) {\n \t\tchar c = *line;\n@@ -675,7 +675,7 @@ static char *find_name_common(const char *line, const char *def,\n \t\t\t\tbreak;\n \t\t}\n \t\tline++;\n-\t\tif (c == '/' && !--p_value)\n+\t\tif (c == '/' && !--p_v)\n \t\t\tstart = line;\n \t}\n \tif (!start)\n@@ -704,24 +704,24 @@ static char *find_name_common(const char *line, const char *def,\n \treturn squash_slash(xmemdupz(start, len));\n }\n \n-static char *find_name(const char *line, char *def, int p_value, int terminate)\n+static char *find_name(const char *line, char *def, int p_v, int terminate)\n {\n \tif (*line == '\"') {\n-\t\tchar *name = find_name_gnu(line, def, p_value);\n+\t\tchar *name = find_name_gnu(line, def, p_v);\n \t\tif (name)\n \t\t\treturn name;\n \t}\n \n-\treturn find_name_common(line, def, p_value, NULL, terminate);\n+\treturn find_name_common(line, def, p_v, NULL, terminate);\n }\n \n-static char *find_name_traditional(const char *line, char *def, int p_value)\n+static char *find_name_traditional(const char *line, char *def, int p_v)\n {\n \tsize_t len;\n \tsize_t date_len;\n \n \tif (*line == '\"') {\n-\t\tchar *name = find_name_gnu(line, def, p_value);\n+\t\tchar *name = find_name_gnu(line, def, p_v);\n \t\tif (name)\n \t\t\treturn name;\n \t}\n@@ -729,10 +729,10 @@ static char *find_name_traditional(const char *line, char *def, int p_value)\n \tlen = strchrnul(line, '\\n') - line;\n \tdate_len = diff_timestamp_len(line, len);\n \tif (!date_len)\n-\t\treturn find_name_common(line, def, p_value, NULL, TERM_TAB);\n+\t\treturn find_name_common(line, def, p_v, NULL, TERM_TAB);\n \tlen -= date_len;\n \n-\treturn find_name_common(line, def, p_value, line + len, 0);\n+\treturn find_name_common(line, def, p_v, line + len, 0);\n }\n \n static int count_slashes(const char *cp)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280426","messageId":"1457545756-20616-3-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 02/48] builtin/apply: avoid parameter shadowing 'linenr' global","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:30Z","receivedAt":"2016-03-09T17:48:30Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 7d9be63..3f740c7 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -1525,7 +1525,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc\n \treturn -1;\n }\n \n-static void record_ws_error(unsigned result, const char *line, int len, int linenr)\n+static void record_ws_error(unsigned result, const char *line, int len, int l_nr)\n {\n \tchar *err;\n \n@@ -1539,7 +1539,7 @@ static void record_ws_error(unsigned result, const char *line, int len, int line\n \n \terr = whitespace_error_string(result);\n \tfprintf(stderr, \"%s:%d: %s.\\n%.*s\\n\",\n-\t\tpatch_input_file, linenr, err, len, line);\n+\t\tpatch_input_file, l_nr, err, len, line);\n \tfree(err);\n }\n \n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280425","messageId":"1457545756-20616-4-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 03/48] builtin/apply: avoid local variable shadowing 'len' parameter","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:31Z","receivedAt":"2016-03-09T17:48:31Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 20 ++++++++++----------\n 1 file changed, 10 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 3f740c7..c99c859 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2196,17 +2196,17 @@ static void update_pre_post_images(struct image *preimage,\n \tfixed = preimage->buf;\n \n \tfor (i = reduced = ctx = 0; i < postimage->nr; i++) {\n-\t\tsize_t len = postimage->line[i].len;\n+\t\tsize_t l_len = postimage->line[i].len;\n \t\tif (!(postimage->line[i].flag & LINE_COMMON)) {\n \t\t\t/* an added line -- no counterparts in preimage */\n-\t\t\tmemmove(new, old, len);\n-\t\t\told += len;\n-\t\t\tnew += len;\n+\t\t\tmemmove(new, old, l_len);\n+\t\t\told += l_len;\n+\t\t\tnew += l_len;\n \t\t\tcontinue;\n \t\t}\n \n \t\t/* a common context -- skip it in the original postimage */\n-\t\told += len;\n+\t\told += l_len;\n \n \t\t/* and find the corresponding one in the fixed preimage */\n \t\twhile (ctx < preimage->nr &&\n@@ -2225,11 +2225,11 @@ static void update_pre_post_images(struct image *preimage,\n \t\t}\n \n \t\t/* and copy it in, while fixing the line length */\n-\t\tlen = preimage->line[ctx].len;\n-\t\tmemcpy(new, fixed, len);\n-\t\tnew += len;\n-\t\tfixed += len;\n-\t\tpostimage->line[i].len = len;\n+\t\tl_len = preimage->line[ctx].len;\n+\t\tmemcpy(new, fixed, l_len);\n+\t\tnew += l_len;\n+\t\tfixed += l_len;\n+\t\tpostimage->line[i].len = l_len;\n \t\tctx++;\n \t}\n \n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280428","messageId":"1457545756-20616-5-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 04/48] builtin/apply: extract line_by_line_fuzzy_match() from match_fragment()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:32Z","receivedAt":"2016-03-09T17:48:32Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 125 ++++++++++++++++++++++++++++++++------------------------\n 1 file changed, 71 insertions(+), 54 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex c99c859..7d7a8ab 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2244,6 +2244,74 @@ static void update_pre_post_images(struct image *preimage,\n \tpostimage->nr -= reduced;\n }\n \n+static int line_by_line_fuzzy_match(struct image *img,\n+\t\t\t\t    struct image *preimage,\n+\t\t\t\t    struct image *postimage,\n+\t\t\t\t    unsigned long try,\n+\t\t\t\t    int try_lno,\n+\t\t\t\t    int preimage_limit)\n+{\n+\tint i;\n+\tsize_t imgoff = 0;\n+\tsize_t preoff = 0;\n+\tsize_t postlen = postimage->len;\n+\tsize_t extra_chars;\n+\tchar *buf;\n+\tchar *preimage_eof;\n+\tchar *preimage_end;\n+\tstruct strbuf fixed;\n+\tchar *fixed_buf;\n+\tsize_t fixed_len;\n+\n+\tfor (i = 0; i < preimage_limit; i++) {\n+\t\tsize_t prelen = preimage->line[i].len;\n+\t\tsize_t imglen = img->line[try_lno+i].len;\n+\n+\t\tif (!fuzzy_matchlines(img->buf + try + imgoff, imglen,\n+\t\t\t\t      preimage->buf + preoff, prelen))\n+\t\t\treturn 0;\n+\t\tif (preimage->line[i].flag & LINE_COMMON)\n+\t\t\tpostlen += imglen - prelen;\n+\t\timgoff += imglen;\n+\t\tpreoff += prelen;\n+\t}\n+\n+\t/*\n+\t * Ok, the preimage matches with whitespace fuzz.\n+\t *\n+\t * imgoff now holds the true length of the target that\n+\t * matches the preimage before the end of the file.\n+\t *\n+\t * Count the number of characters in the preimage that fall\n+\t * beyond the end of the file and make sure that all of them\n+\t * are whitespace characters. (This can only happen if\n+\t * we are removing blank lines at the end of the file.)\n+\t */\n+\tbuf = preimage_eof = preimage->buf + preoff;\n+\tfor ( ; i < preimage->nr; i++)\n+\t\tpreoff += preimage->line[i].len;\n+\tpreimage_end = preimage->buf + preoff;\n+\tfor ( ; buf < preimage_end; buf++)\n+\t\tif (!isspace(*buf))\n+\t\t\treturn 0;\n+\n+\t/*\n+\t * Update the preimage and the common postimage context\n+\t * lines to use the same whitespace as the target.\n+\t * If whitespace is missing in the target (i.e.\n+\t * if the preimage extends beyond the end of the file),\n+\t * use the whitespace from the preimage.\n+\t */\n+\textra_chars = preimage_end - preimage_eof;\n+\tstrbuf_init(&fixed, imgoff + extra_chars);\n+\tstrbuf_add(&fixed, img->buf + try, imgoff);\n+\tstrbuf_add(&fixed, preimage_eof, extra_chars);\n+\tfixed_buf = strbuf_detach(&fixed, &fixed_len);\n+\tupdate_pre_post_images(preimage, postimage,\n+\t\t\t       fixed_buf, fixed_len, postlen);\n+\treturn 1;\n+}\n+\n static int match_fragment(struct image *img,\n \t\t\t  struct image *preimage,\n \t\t\t  struct image *postimage,\n@@ -2253,7 +2321,7 @@ static int match_fragment(struct image *img,\n \t\t\t  int match_beginning, int match_end)\n {\n \tint i;\n-\tchar *fixed_buf, *buf, *orig, *target;\n+\tchar *fixed_buf, *orig, *target;\n \tstruct strbuf fixed;\n \tsize_t fixed_len, postlen;\n \tint preimage_limit;\n@@ -2314,6 +2382,7 @@ static int match_fragment(struct image *img,\n \t\t * There must be one non-blank context line that match\n \t\t * a line before the end of img.\n \t\t */\n+\t\tchar *buf;\n \t\tchar *buf_end;\n \n \t\tbuf = preimage->buf;\n@@ -2334,59 +2403,7 @@ static int match_fragment(struct image *img,\n \t * we need it to adjust whitespace if we match.\n \t */\n \tif (ws_ignore_action == ignore_ws_change) {\n-\t\tsize_t imgoff = 0;\n-\t\tsize_t preoff = 0;\n-\t\tsize_t postlen = postimage->len;\n-\t\tsize_t extra_chars;\n-\t\tchar *preimage_eof;\n-\t\tchar *preimage_end;\n-\t\tfor (i = 0; i < preimage_limit; i++) {\n-\t\t\tsize_t prelen = preimage->line[i].len;\n-\t\t\tsize_t imglen = img->line[try_lno+i].len;\n-\n-\t\t\tif (!fuzzy_matchlines(img->buf + try + imgoff, imglen,\n-\t\t\t\t\t      preimage->buf + preoff, prelen))\n-\t\t\t\treturn 0;\n-\t\t\tif (preimage->line[i].flag & LINE_COMMON)\n-\t\t\t\tpostlen += imglen - prelen;\n-\t\t\timgoff += imglen;\n-\t\t\tpreoff += prelen;\n-\t\t}\n-\n-\t\t/*\n-\t\t * Ok, the preimage matches with whitespace fuzz.\n-\t\t *\n-\t\t * imgoff now holds the true length of the target that\n-\t\t * matches the preimage before the end of the file.\n-\t\t *\n-\t\t * Count the number of characters in the preimage that fall\n-\t\t * beyond the end of the file and make sure that all of them\n-\t\t * are whitespace characters. (This can only happen if\n-\t\t * we are removing blank lines at the end of the file.)\n-\t\t */\n-\t\tbuf = preimage_eof = preimage->buf + preoff;\n-\t\tfor ( ; i < preimage->nr; i++)\n-\t\t\tpreoff += preimage->line[i].len;\n-\t\tpreimage_end = preimage->buf + preoff;\n-\t\tfor ( ; buf < preimage_end; buf++)\n-\t\t\tif (!isspace(*buf))\n-\t\t\t\treturn 0;\n-\n-\t\t/*\n-\t\t * Update the preimage and the common postimage context\n-\t\t * lines to use the same whitespace as the target.\n-\t\t * If whitespace is missing in the target (i.e.\n-\t\t * if the preimage extends beyond the end of the file),\n-\t\t * use the whitespace from the preimage.\n-\t\t */\n-\t\textra_chars = preimage_end - preimage_eof;\n-\t\tstrbuf_init(&fixed, imgoff + extra_chars);\n-\t\tstrbuf_add(&fixed, img->buf + try, imgoff);\n-\t\tstrbuf_add(&fixed, preimage_eof, extra_chars);\n-\t\tfixed_buf = strbuf_detach(&fixed, &fixed_len);\n-\t\tupdate_pre_post_images(preimage, postimage,\n-\t\t\t\tfixed_buf, fixed_len, postlen);\n-\t\treturn 1;\n+\t\treturn line_by_line_fuzzy_match(img, preimage, postimage, try, try_lno, preimage_limit);\n \t}\n \n \tif (ws_error_action != correct_ws_error)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280427","messageId":"1457545756-20616-6-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 05/48] builtin/apply: move 'options' variable into cmd_apply()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:33Z","receivedAt":"2016-03-09T17:48:33Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 7d7a8ab..838e46a 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -79,7 +79,6 @@ static enum ws_ignore {\n static const char *patch_input_file;\n static struct strbuf root = STRBUF_INIT;\n static int read_stdin = 1;\n-static int options;\n \n static void parse_whitespace_option(const char *option)\n {\n@@ -4516,6 +4515,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tint errs = 0;\n \tint is_not_gitdir = !startup_info->have_repository;\n \tint force_apply = 0;\n+\tint options = 0;\n \n \tconst char *whitespace_option = NULL;\n \n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280429","messageId":"1457545756-20616-7-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 06/48] builtin/apply: introduce 'struct apply_state' to start libifying","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:34Z","receivedAt":"2016-03-09T17:48:34Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 94 ++++++++++++++++++++++++++++++++++-----------------------\n 1 file changed, 56 insertions(+), 38 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 838e46a..462e28f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -21,6 +21,11 @@\n #include \"ll-merge.h\"\n #include \"rerere.h\"\n \n+struct apply_state {\n+\tconst char *prefix;\n+\tint prefix_length;\n+};\n+\n /*\n  *  --check turns on checking that the working tree matches the\n  *    files that are being modified, but doesn't apply the patch\n@@ -30,8 +35,6 @@\n  *  --index updates the cache as well.\n  *  --cached updates only the cache without ever touching the working tree.\n  */\n-static const char *prefix;\n-static int prefix_length = -1;\n static int newfd = -1;\n \n static int unidiff_zero;\n@@ -749,7 +752,7 @@ static int count_slashes(const char *cp)\n  * Given the string after \"--- \" or \"+++ \", guess the appropriate\n  * p_value for the given patch.\n  */\n-static int guess_p_value(const char *nameline)\n+static int guess_p_value(struct apply_state *state, const char *nameline)\n {\n \tchar *name, *cp;\n \tint val = -1;\n@@ -762,17 +765,17 @@ static int guess_p_value(const char *nameline)\n \tcp = strchr(name, '/');\n \tif (!cp)\n \t\tval = 0;\n-\telse if (prefix) {\n+\telse if (state->prefix) {\n \t\t/*\n \t\t * Does it begin with \"a/$our-prefix\" and such?  Then this is\n \t\t * very likely to apply to our directory.\n \t\t */\n-\t\tif (!strncmp(name, prefix, prefix_length))\n-\t\t\tval = count_slashes(prefix);\n+\t\tif (!strncmp(name, state->prefix, state->prefix_length))\n+\t\t\tval = count_slashes(state->prefix);\n \t\telse {\n \t\t\tcp++;\n-\t\t\tif (!strncmp(cp, prefix, prefix_length))\n-\t\t\t\tval = count_slashes(prefix) + 1;\n+\t\t\tif (!strncmp(cp, state->prefix, state->prefix_length))\n+\t\t\t\tval = count_slashes(state->prefix) + 1;\n \t\t}\n \t}\n \tfree(name);\n@@ -859,7 +862,10 @@ static int has_epoch_timestamp(const char *nameline)\n  * files, we can happily check the index for a match, but for creating a\n  * new file we should try to match whatever \"patch\" does. I have no idea.\n  */\n-static void parse_traditional_patch(const char *first, const char *second, struct patch *patch)\n+static void parse_traditional_patch(struct apply_state *state,\n+\t\t\t\t    const char *first,\n+\t\t\t\t    const char *second,\n+\t\t\t\t    struct patch *patch)\n {\n \tchar *name;\n \n@@ -867,8 +873,8 @@ static void parse_traditional_patch(const char *first, const char *second, struc\n \tsecond += 4;\t/* skip \"+++ \" */\n \tif (!p_value_known) {\n \t\tint p, q;\n-\t\tp = guess_p_value(first);\n-\t\tq = guess_p_value(second);\n+\t\tp = guess_p_value(state, first);\n+\t\tq = guess_p_value(state, second);\n \t\tif (p < 0) p = q;\n \t\tif (0 <= p && p == q) {\n \t\t\tp_value = p;\n@@ -1439,7 +1445,11 @@ static int parse_fragment_header(const char *line, int len, struct fragment *fra\n \treturn offset;\n }\n \n-static int find_header(const char *line, unsigned long size, int *hdrsize, struct patch *patch)\n+static int find_header(struct apply_state *state,\n+\t\t       const char *line,\n+\t\t       unsigned long size,\n+\t\t       int *hdrsize,\n+\t\t       struct patch *patch)\n {\n \tunsigned long offset, len;\n \n@@ -1516,7 +1526,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc\n \t\t\tcontinue;\n \n \t\t/* Ok, we'll consider it a patch */\n-\t\tparse_traditional_patch(line, line+len, patch);\n+\t\tparse_traditional_patch(state, line, line+len, patch);\n \t\t*hdrsize = len + nextlen;\n \t\tlinenr += 2;\n \t\treturn offset;\n@@ -1918,21 +1928,21 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)\n \treturn used;\n }\n \n-static void prefix_one(char **name)\n+static void prefix_one(struct apply_state *state, char **name)\n {\n \tchar *old_name = *name;\n \tif (!old_name)\n \t\treturn;\n-\t*name = xstrdup(prefix_filename(prefix, prefix_length, *name));\n+\t*name = xstrdup(prefix_filename(state->prefix, state->prefix_length, *name));\n \tfree(old_name);\n }\n \n-static void prefix_patch(struct patch *p)\n+static void prefix_patch(struct apply_state *state, struct patch *p)\n {\n-\tif (!prefix || p->is_toplevel_relative)\n+\tif (!state->prefix || p->is_toplevel_relative)\n \t\treturn;\n-\tprefix_one(&p->new_name);\n-\tprefix_one(&p->old_name);\n+\tprefix_one(state, &p->new_name);\n+\tprefix_one(state, &p->old_name);\n }\n \n /*\n@@ -1949,16 +1959,16 @@ static void add_name_limit(const char *name, int exclude)\n \tit->util = exclude ? NULL : (void *) 1;\n }\n \n-static int use_patch(struct patch *p)\n+static int use_patch(struct apply_state *state, struct patch *p)\n {\n \tconst char *pathname = p->new_name ? p->new_name : p->old_name;\n \tint i;\n \n \t/* Paths outside are not touched regardless of \"--include\" */\n-\tif (0 < prefix_length) {\n+\tif (0 < state->prefix_length) {\n \t\tint pathlen = strlen(pathname);\n-\t\tif (pathlen <= prefix_length ||\n-\t\t    memcmp(prefix, pathname, prefix_length))\n+\t\tif (pathlen <= state->prefix_length ||\n+\t\t    memcmp(state->prefix, pathname, state->prefix_length))\n \t\t\treturn 0;\n \t}\n \n@@ -1985,17 +1995,17 @@ static int use_patch(struct patch *p)\n  * Return the number of bytes consumed, so that the caller can call us\n  * again for the next patch.\n  */\n-static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)\n+static int parse_chunk(struct apply_state *state, char *buffer, unsigned long size, struct patch *patch)\n {\n \tint hdrsize, patchsize;\n-\tint offset = find_header(buffer, size, &hdrsize, patch);\n+\tint offset = find_header(state, buffer, size, &hdrsize, patch);\n \n \tif (offset < 0)\n \t\treturn offset;\n \n-\tprefix_patch(patch);\n+\tprefix_patch(state, patch);\n \n-\tif (!use_patch(patch))\n+\tif (!use_patch(state, patch))\n \t\tpatch->ws_rule = 0;\n \telse\n \t\tpatch->ws_rule = whitespace_rule(patch->new_name\n@@ -4371,7 +4381,10 @@ static struct lock_file lock_file;\n #define INACCURATE_EOF\t(1<<0)\n #define RECOUNT\t\t(1<<1)\n \n-static int apply_patch(int fd, const char *filename, int options)\n+static int apply_patch(struct apply_state *state,\n+\t\t       int fd,\n+\t\t       const char *filename,\n+\t\t       int options)\n {\n \tsize_t offset;\n \tstruct strbuf buf = STRBUF_INIT; /* owns the patch text */\n@@ -4388,12 +4401,12 @@ static int apply_patch(int fd, const char *filename, int options)\n \t\tpatch = xcalloc(1, sizeof(*patch));\n \t\tpatch->inaccurate_eof = !!(options & INACCURATE_EOF);\n \t\tpatch->recount =  !!(options & RECOUNT);\n-\t\tnr = parse_chunk(buf.buf + offset, buf.len - offset, patch);\n+\t\tnr = parse_chunk(state, buf.buf + offset, buf.len - offset, patch);\n \t\tif (nr < 0)\n \t\t\tbreak;\n \t\tif (apply_in_reverse)\n \t\t\treverse_patches(patch);\n-\t\tif (use_patch(patch)) {\n+\t\tif (use_patch(state, patch)) {\n \t\t\tpatch_stats(patch);\n \t\t\t*listp = patch;\n \t\t\tlistp = &patch->next;\n@@ -4516,6 +4529,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tint is_not_gitdir = !startup_info->have_repository;\n \tint force_apply = 0;\n \tint options = 0;\n+\tstruct apply_state state;\n \n \tconst char *whitespace_option = NULL;\n \n@@ -4588,15 +4602,17 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tOPT_END()\n \t};\n \n-\tprefix = prefix_;\n-\tprefix_length = prefix ? strlen(prefix) : 0;\n+\tmemset(&state, 0, sizeof(state));\n+\tstate.prefix = prefix_;\n+\tstate.prefix_length = state.prefix ? strlen(state.prefix) : 0;\n+\n \tgit_apply_config();\n \tif (apply_default_whitespace)\n \t\tparse_whitespace_option(apply_default_whitespace);\n \tif (apply_default_ignorewhitespace)\n \t\tparse_ignorewhitespace_option(apply_default_ignorewhitespace);\n \n-\targc = parse_options(argc, argv, prefix, builtin_apply_options,\n+\targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n \n \tif (apply_with_reject && threeway)\n@@ -4627,23 +4643,25 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tint fd;\n \n \t\tif (!strcmp(arg, \"-\")) {\n-\t\t\terrs |= apply_patch(0, \"<stdin>\", options);\n+\t\t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n \t\t\tread_stdin = 0;\n \t\t\tcontinue;\n-\t\t} else if (0 < prefix_length)\n-\t\t\targ = prefix_filename(prefix, prefix_length, arg);\n+\t\t} else if (0 < state.prefix_length)\n+\t\t\targ = prefix_filename(state.prefix,\n+\t\t\t\t\t      state.prefix_length,\n+\t\t\t\t\t      arg);\n \n \t\tfd = open(arg, O_RDONLY);\n \t\tif (fd < 0)\n \t\t\tdie_errno(_(\"can't open patch '%s'\"), arg);\n \t\tread_stdin = 0;\n \t\tset_default_whitespace_mode(whitespace_option);\n-\t\terrs |= apply_patch(fd, arg, options);\n+\t\terrs |= apply_patch(&state, fd, arg, options);\n \t\tclose(fd);\n \t}\n \tset_default_whitespace_mode(whitespace_option);\n \tif (read_stdin)\n-\t\terrs |= apply_patch(0, \"<stdin>\", options);\n+\t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n \tif (whitespace_error) {\n \t\tif (squelch_whitespace_errors &&\n \t\t    squelch_whitespace_errors < whitespace_error) {\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280430","messageId":"1457545756-20616-8-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 07/48] builtin/apply: move 'newfd' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:35Z","receivedAt":"2016-03-09T17:48:35Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 462e28f..d56dd9f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -24,6 +24,7 @@\n struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n+\tint newfd;\n };\n \n /*\n@@ -35,7 +36,6 @@ struct apply_state {\n  *  --index updates the cache as well.\n  *  --cached updates only the cache without ever touching the working tree.\n  */\n-static int newfd = -1;\n \n static int unidiff_zero;\n static int p_value = 1;\n@@ -4425,8 +4425,8 @@ static int apply_patch(struct apply_state *state,\n \t\tapply = 0;\n \n \tupdate_index = check_index && apply;\n-\tif (update_index && newfd < 0)\n-\t\tnewfd = hold_locked_index(&lock_file, 1);\n+\tif (update_index && state->newfd < 0)\n+\t\tstate->newfd = hold_locked_index(&lock_file, 1);\n \n \tif (check_index) {\n \t\tif (read_cache() < 0)\n@@ -4605,6 +4605,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tmemset(&state, 0, sizeof(state));\n \tstate.prefix = prefix_;\n \tstate.prefix_length = state.prefix ? strlen(state.prefix) : 0;\n+\tstate.newfd = -1;\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280431","messageId":"1457545756-20616-9-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 08/48] builtin/apply: move 'unidiff_zero' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:36Z","receivedAt":"2016-03-09T17:48:36Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 42 ++++++++++++++++++++++++------------------\n 1 file changed, 24 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex d56dd9f..d5bc30f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -25,6 +25,8 @@ struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n \tint newfd;\n+\n+\tint unidiff_zero;\n };\n \n /*\n@@ -37,7 +39,6 @@ struct apply_state {\n  *  --cached updates only the cache without ever touching the working tree.\n  */\n \n-static int unidiff_zero;\n static int p_value = 1;\n static int p_value_known;\n static int check_index;\n@@ -2698,7 +2699,8 @@ static void update_image(struct image *img,\n  * postimage) for the hunk.  Find lines that match \"preimage\" in \"img\" and\n  * replace the part of \"img\" with \"postimage\" text.\n  */\n-static int apply_one_fragment(struct image *img, struct fragment *frag,\n+static int apply_one_fragment(struct apply_state *state,\n+\t\t\t      struct image *img, struct fragment *frag,\n \t\t\t      int inaccurate_eof, unsigned ws_rule,\n \t\t\t      int nth_fragment)\n {\n@@ -2840,7 +2842,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,\n \t * without leading context must match at the beginning.\n \t */\n \tmatch_beginning = (!frag->oldpos ||\n-\t\t\t   (frag->oldpos == 1 && !unidiff_zero));\n+\t\t\t   (frag->oldpos == 1 && !state->unidiff_zero));\n \n \t/*\n \t * A hunk without trailing lines must match at the end.\n@@ -2848,7 +2850,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,\n \t * from the lack of trailing lines if the patch was generated\n \t * with unidiff without any context.\n \t */\n-\tmatch_end = !unidiff_zero && !trailing;\n+\tmatch_end = !state->unidiff_zero && !trailing;\n \n \tpos = frag->newpos ? (frag->newpos - 1) : 0;\n \tpreimage.buf = oldlines;\n@@ -3071,7 +3073,7 @@ static int apply_binary(struct image *img, struct patch *patch)\n \treturn 0;\n }\n \n-static int apply_fragments(struct image *img, struct patch *patch)\n+static int apply_fragments(struct apply_state *state, struct image *img, struct patch *patch)\n {\n \tstruct fragment *frag = patch->fragments;\n \tconst char *name = patch->old_name ? patch->old_name : patch->new_name;\n@@ -3084,7 +3086,7 @@ static int apply_fragments(struct image *img, struct patch *patch)\n \n \twhile (frag) {\n \t\tnth++;\n-\t\tif (apply_one_fragment(img, frag, inaccurate_eof, ws_rule, nth)) {\n+\t\tif (apply_one_fragment(state, img, frag, inaccurate_eof, ws_rule, nth)) {\n \t\t\terror(_(\"patch failed: %s:%ld\"), name, frag->oldpos);\n \t\t\tif (!apply_with_reject)\n \t\t\t\treturn -1;\n@@ -3392,8 +3394,11 @@ static int load_current(struct image *image, struct patch *patch)\n \treturn 0;\n }\n \n-static int try_threeway(struct image *image, struct patch *patch,\n-\t\t\tstruct stat *st, const struct cache_entry *ce)\n+static int try_threeway(struct apply_state *state,\n+\t\t\tstruct image *image,\n+\t\t\tstruct patch *patch,\n+\t\t\tstruct stat *st,\n+\t\t\tconst struct cache_entry *ce)\n {\n \tunsigned char pre_sha1[20], post_sha1[20], our_sha1[20];\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -3419,7 +3424,7 @@ static int try_threeway(struct image *image, struct patch *patch,\n \timg = strbuf_detach(&buf, &len);\n \tprepare_image(&tmp_image, img, len, 1);\n \t/* Apply the patch to get the post image */\n-\tif (apply_fragments(&tmp_image, patch) < 0) {\n+\tif (apply_fragments(state, &tmp_image, patch) < 0) {\n \t\tclear_image(&tmp_image);\n \t\treturn -1;\n \t}\n@@ -3463,7 +3468,8 @@ static int try_threeway(struct image *image, struct patch *patch,\n \treturn 0;\n }\n \n-static int apply_data(struct patch *patch, struct stat *st, const struct cache_entry *ce)\n+static int apply_data(struct apply_state *state, struct patch *patch,\n+\t\t      struct stat *st, const struct cache_entry *ce)\n {\n \tstruct image image;\n \n@@ -3471,9 +3477,9 @@ static int apply_data(struct patch *patch, struct stat *st, const struct cache_e\n \t\treturn -1;\n \n \tif (patch->direct_to_threeway ||\n-\t    apply_fragments(&image, patch) < 0) {\n+\t    apply_fragments(state, &image, patch) < 0) {\n \t\t/* Note: with --reject, apply_fragments() returns 0 */\n-\t\tif (!threeway || try_threeway(&image, patch, st, ce) < 0)\n+\t\tif (!threeway || try_threeway(state, &image, patch, st, ce) < 0)\n \t\t\treturn -1;\n \t}\n \tpatch->result = image.buf;\n@@ -3721,7 +3727,7 @@ static void die_on_unsafe_path(struct patch *patch)\n  * Check and apply the patch in-core; leave the result in patch->result\n  * for the caller to write it out to the final destination.\n  */\n-static int check_patch(struct patch *patch)\n+static int check_patch(struct apply_state *state, struct patch *patch)\n {\n \tstruct stat st;\n \tconst char *old_name = patch->old_name;\n@@ -3820,13 +3826,13 @@ static int check_patch(struct patch *patch)\n \t\treturn error(_(\"affected file '%s' is beyond a symbolic link\"),\n \t\t\t     patch->new_name);\n \n-\tif (apply_data(patch, &st, ce) < 0)\n+\tif (apply_data(state, patch, &st, ce) < 0)\n \t\treturn error(_(\"%s: patch does not apply\"), name);\n \tpatch->rejected = 0;\n \treturn 0;\n }\n \n-static int check_patch_list(struct patch *patch)\n+static int check_patch_list(struct apply_state *state, struct patch *patch)\n {\n \tint err = 0;\n \n@@ -3836,7 +3842,7 @@ static int check_patch_list(struct patch *patch)\n \t\tif (apply_verbosely)\n \t\t\tsay_patch_name(stderr,\n \t\t\t\t       _(\"Checking patch %s...\"), patch);\n-\t\terr |= check_patch(patch);\n+\t\terr |= check_patch(state, patch);\n \t\tpatch = patch->next;\n \t}\n \treturn err;\n@@ -4434,7 +4440,7 @@ static int apply_patch(struct apply_state *state,\n \t}\n \n \tif ((check || apply) &&\n-\t    check_patch_list(list) < 0 &&\n+\t    check_patch_list(state, list) < 0 &&\n \t    !apply_with_reject)\n \t\texit(1);\n \n@@ -4583,7 +4589,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tPARSE_OPT_NOARG, option_parse_space_change },\n \t\tOPT_BOOL('R', \"reverse\", &apply_in_reverse,\n \t\t\tN_(\"apply the patch in reverse\")),\n-\t\tOPT_BOOL(0, \"unidiff-zero\", &unidiff_zero,\n+\t\tOPT_BOOL(0, \"unidiff-zero\", &state.unidiff_zero,\n \t\t\tN_(\"don't expect at least one line of context\")),\n \t\tOPT_BOOL(0, \"reject\", &apply_with_reject,\n \t\t\tN_(\"leave the rejected hunks in corresponding *.rej files\")),\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280433","messageId":"1457545756-20616-10-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 09/48] builtin/apply: move 'check' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:37Z","receivedAt":"2016-03-09T17:48:37Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 16 +++++++++-------\n 1 file changed, 9 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex d5bc30f..37879de 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -26,12 +26,15 @@ struct apply_state {\n \tint prefix_length;\n \tint newfd;\n \n+\t/*\n+\t *  --check turns on checking that the working tree matches the\n+\t *    files that are being modified, but doesn't apply the patch\n+\t */\n+\tint check;\n \tint unidiff_zero;\n };\n \n /*\n- *  --check turns on checking that the working tree matches the\n- *    files that are being modified, but doesn't apply the patch\n  *  --stat does just a diffstat, and doesn't actually apply\n  *  --numstat does numeric diffstat, and doesn't actually apply\n  *  --index-info shows the old and new index info for paths if available.\n@@ -47,7 +50,6 @@ static int cached;\n static int diffstat;\n static int numstat;\n static int summary;\n-static int check;\n static int apply = 1;\n static int apply_in_reverse;\n static int apply_with_reject;\n@@ -2055,7 +2057,7 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\t * without metadata change.  A binary patch appears\n \t\t * empty to us here.\n \t\t */\n-\t\tif ((apply || check) &&\n+\t\tif ((apply || state->check) &&\n \t\t    (!patch->is_binary && !metadata_changes(patch)))\n \t\t\tdie(_(\"patch with only garbage at line %d\"), linenr);\n \t}\n@@ -4439,7 +4441,7 @@ static int apply_patch(struct apply_state *state,\n \t\t\tdie(_(\"unable to read index file\"));\n \t}\n \n-\tif ((check || apply) &&\n+\tif ((state->check || apply) &&\n \t    check_patch_list(state, list) < 0 &&\n \t    !apply_with_reject)\n \t\texit(1);\n@@ -4559,7 +4561,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"show number of added and deleted lines in decimal notation\")),\n \t\tOPT_BOOL(0, \"summary\", &summary,\n \t\t\tN_(\"instead of applying the patch, output a summary for the input\")),\n-\t\tOPT_BOOL(0, \"check\", &check,\n+\t\tOPT_BOOL(0, \"check\", &state.check,\n \t\t\tN_(\"instead of applying the patch, see if the patch is applicable\")),\n \t\tOPT_BOOL(0, \"index\", &check_index,\n \t\t\tN_(\"make sure the patch is applicable to the current index\")),\n@@ -4633,7 +4635,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t}\n \tif (apply_with_reject)\n \t\tapply = apply_verbosely = 1;\n-\tif (!force_apply && (diffstat || numstat || summary || check || fake_ancestor))\n+\tif (!force_apply && (diffstat || numstat || summary || state.check || fake_ancestor))\n \t\tapply = 0;\n \tif (check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280435","messageId":"1457545756-20616-11-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 10/48] builtin/apply: move 'check_index' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:38Z","receivedAt":"2016-03-09T17:48:38Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 69 +++++++++++++++++++++++++++++++++------------------------\n 1 file changed, 40 insertions(+), 29 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 37879de..9bc01a8 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -31,6 +31,10 @@ struct apply_state {\n \t *    files that are being modified, but doesn't apply the patch\n \t */\n \tint check;\n+\n+\t/* --index updates the cache as well. */\n+\tint check_index;\n+\n \tint unidiff_zero;\n };\n \n@@ -38,13 +42,11 @@ struct apply_state {\n  *  --stat does just a diffstat, and doesn't actually apply\n  *  --numstat does numeric diffstat, and doesn't actually apply\n  *  --index-info shows the old and new index info for paths if available.\n- *  --index updates the cache as well.\n  *  --cached updates only the cache without ever touching the working tree.\n  */\n \n static int p_value = 1;\n static int p_value_known;\n-static int check_index;\n static int update_index;\n static int cached;\n static int diffstat;\n@@ -3250,13 +3252,14 @@ static int verify_index_match(const struct cache_entry *ce, struct stat *st)\n \n #define SUBMODULE_PATCH_WITHOUT_INDEX 1\n \n-static int load_patch_target(struct strbuf *buf,\n+static int load_patch_target(struct apply_state *state,\n+\t\t\t     struct strbuf *buf,\n \t\t\t     const struct cache_entry *ce,\n \t\t\t     struct stat *st,\n \t\t\t     const char *name,\n \t\t\t     unsigned expected_mode)\n {\n-\tif (cached || check_index) {\n+\tif (cached || state->check_index) {\n \t\tif (read_file_or_gitlink(ce, buf))\n \t\t\treturn error(_(\"read of %s failed\"), name);\n \t} else if (name) {\n@@ -3282,7 +3285,8 @@ static int load_patch_target(struct strbuf *buf,\n  * applying a non-git patch that incrementally updates the tree,\n  * we read from the result of a previous diff.\n  */\n-static int load_preimage(struct image *image,\n+static int load_preimage(struct apply_state *state,\n+\t\t\t struct image *image,\n \t\t\t struct patch *patch, struct stat *st,\n \t\t\t const struct cache_entry *ce)\n {\n@@ -3300,7 +3304,7 @@ static int load_preimage(struct image *image,\n \t\t/* We have a patched copy in memory; use that. */\n \t\tstrbuf_add(&buf, previous->result, previous->resultsize);\n \t} else {\n-\t\tstatus = load_patch_target(&buf, ce, st,\n+\t\tstatus = load_patch_target(state, &buf, ce, st,\n \t\t\t\t\t   patch->old_name, patch->old_mode);\n \t\tif (status < 0)\n \t\t\treturn status;\n@@ -3359,7 +3363,9 @@ static int three_way_merge(struct image *image,\n  * the current contents of the new_name.  In no cases other than that\n  * this function will be called.\n  */\n-static int load_current(struct image *image, struct patch *patch)\n+static int load_current(struct apply_state *state,\n+\t\t\tstruct image *image,\n+\t\t\tstruct patch *patch)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tint status, pos;\n@@ -3386,7 +3392,7 @@ static int load_current(struct image *image, struct patch *patch)\n \tif (verify_index_match(ce, &st))\n \t\treturn error(_(\"%s: does not match index\"), name);\n \n-\tstatus = load_patch_target(&buf, ce, &st, name, mode);\n+\tstatus = load_patch_target(state, &buf, ce, &st, name, mode);\n \tif (status < 0)\n \t\treturn status;\n \telse if (status)\n@@ -3436,11 +3442,11 @@ static int try_threeway(struct apply_state *state,\n \n \t/* our_sha1[] is ours */\n \tif (patch->is_new) {\n-\t\tif (load_current(&tmp_image, patch))\n+\t\tif (load_current(state, &tmp_image, patch))\n \t\t\treturn error(\"cannot read the current contents of '%s'\",\n \t\t\t\t     patch->new_name);\n \t} else {\n-\t\tif (load_preimage(&tmp_image, patch, st, ce))\n+\t\tif (load_preimage(state, &tmp_image, patch, st, ce))\n \t\t\treturn error(\"cannot read the current contents of '%s'\",\n \t\t\t\t     patch->old_name);\n \t}\n@@ -3475,7 +3481,7 @@ static int apply_data(struct apply_state *state, struct patch *patch,\n {\n \tstruct image image;\n \n-\tif (load_preimage(&image, patch, st, ce) < 0)\n+\tif (load_preimage(state, &image, patch, st, ce) < 0)\n \t\treturn -1;\n \n \tif (patch->direct_to_threeway ||\n@@ -3506,7 +3512,10 @@ static int apply_data(struct apply_state *state, struct patch *patch,\n  * check_patch() separately makes sure (and errors out otherwise) that\n  * the path the patch creates does not exist in the current tree.\n  */\n-static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)\n+static int check_preimage(struct apply_state *state,\n+\t\t\t  struct patch *patch,\n+\t\t\t  struct cache_entry **ce,\n+\t\t\t  struct stat *st)\n {\n \tconst char *old_name = patch->old_name;\n \tstruct patch *previous = NULL;\n@@ -3529,7 +3538,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s\n \t\t\treturn error(_(\"%s: %s\"), old_name, strerror(errno));\n \t}\n \n-\tif (check_index && !previous) {\n+\tif (state->check_index && !previous) {\n \t\tint pos = cache_name_pos(old_name, strlen(old_name));\n \t\tif (pos < 0) {\n \t\t\tif (patch->is_new < 0)\n@@ -3579,11 +3588,13 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s\n #define EXISTS_IN_INDEX 1\n #define EXISTS_IN_WORKTREE 2\n \n-static int check_to_create(const char *new_name, int ok_if_exists)\n+static int check_to_create(struct apply_state *state,\n+\t\t\t   const char *new_name,\n+\t\t\t   int ok_if_exists)\n {\n \tstruct stat nst;\n \n-\tif (check_index &&\n+\tif (state->check_index &&\n \t    cache_name_pos(new_name, strlen(new_name)) >= 0 &&\n \t    !ok_if_exists)\n \t\treturn EXISTS_IN_INDEX;\n@@ -3659,7 +3670,7 @@ static void prepare_symlink_changes(struct patch *patch)\n \t}\n }\n \n-static int path_is_beyond_symlink_1(struct strbuf *name)\n+static int path_is_beyond_symlink_1(struct apply_state *state, struct strbuf *name)\n {\n \tdo {\n \t\tunsigned int change;\n@@ -3680,7 +3691,7 @@ static int path_is_beyond_symlink_1(struct strbuf *name)\n \t\t\tcontinue;\n \n \t\t/* otherwise, check the preimage */\n-\t\tif (check_index) {\n+\t\tif (state->check_index) {\n \t\t\tstruct cache_entry *ce;\n \n \t\t\tce = cache_file_exists(name->buf, name->len, ignore_case);\n@@ -3695,14 +3706,14 @@ static int path_is_beyond_symlink_1(struct strbuf *name)\n \treturn 0;\n }\n \n-static int path_is_beyond_symlink(const char *name_)\n+static int path_is_beyond_symlink(struct apply_state *state, const char *name_)\n {\n \tint ret;\n \tstruct strbuf name = STRBUF_INIT;\n \n \tassert(*name_ != '\\0');\n \tstrbuf_addstr(&name, name_);\n-\tret = path_is_beyond_symlink_1(&name);\n+\tret = path_is_beyond_symlink_1(state, &name);\n \tstrbuf_release(&name);\n \n \treturn ret;\n@@ -3742,7 +3753,7 @@ static int check_patch(struct apply_state *state, struct patch *patch)\n \n \tpatch->rejected = 1; /* we will drop this after we succeed */\n \n-\tstatus = check_preimage(patch, &ce, &st);\n+\tstatus = check_preimage(state, patch, &ce, &st);\n \tif (status)\n \t\treturn status;\n \told_name = patch->old_name;\n@@ -3769,7 +3780,7 @@ static int check_patch(struct apply_state *state, struct patch *patch)\n \n \tif (new_name &&\n \t    ((0 < patch->is_new) || patch->is_rename || patch->is_copy)) {\n-\t\tint err = check_to_create(new_name, ok_if_exists);\n+\t\tint err = check_to_create(state, new_name, ok_if_exists);\n \n \t\tif (err && threeway) {\n \t\t\tpatch->direct_to_threeway = 1;\n@@ -3824,7 +3835,7 @@ static int check_patch(struct apply_state *state, struct patch *patch)\n \t * is not deposited to a path that is beyond a symbolic link\n \t * here.\n \t */\n-\tif (!patch->is_delete && path_is_beyond_symlink(patch->new_name))\n+\tif (!patch->is_delete && path_is_beyond_symlink(state, patch->new_name))\n \t\treturn error(_(\"affected file '%s' is beyond a symbolic link\"),\n \t\t\t     patch->new_name);\n \n@@ -4432,11 +4443,11 @@ static int apply_patch(struct apply_state *state,\n \tif (whitespace_error && (ws_error_action == die_on_ws_error))\n \t\tapply = 0;\n \n-\tupdate_index = check_index && apply;\n+\tupdate_index = state->check_index && apply;\n \tif (update_index && state->newfd < 0)\n \t\tstate->newfd = hold_locked_index(&lock_file, 1);\n \n-\tif (check_index) {\n+\tif (state->check_index) {\n \t\tif (read_cache() < 0)\n \t\t\tdie(_(\"unable to read index file\"));\n \t}\n@@ -4563,7 +4574,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"instead of applying the patch, output a summary for the input\")),\n \t\tOPT_BOOL(0, \"check\", &state.check,\n \t\t\tN_(\"instead of applying the patch, see if the patch is applicable\")),\n-\t\tOPT_BOOL(0, \"index\", &check_index,\n+\t\tOPT_BOOL(0, \"index\", &state.check_index,\n \t\t\tN_(\"make sure the patch is applicable to the current index\")),\n \t\tOPT_BOOL(0, \"cached\", &cached,\n \t\t\tN_(\"apply a patch without touching the working tree\")),\n@@ -4631,20 +4642,20 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tif (threeway) {\n \t\tif (is_not_gitdir)\n \t\t\tdie(_(\"--3way outside a repository\"));\n-\t\tcheck_index = 1;\n+\t\tstate.check_index = 1;\n \t}\n \tif (apply_with_reject)\n \t\tapply = apply_verbosely = 1;\n \tif (!force_apply && (diffstat || numstat || summary || state.check || fake_ancestor))\n \t\tapply = 0;\n-\tif (check_index && is_not_gitdir)\n+\tif (state.check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n \tif (cached) {\n \t\tif (is_not_gitdir)\n \t\t\tdie(_(\"--cached outside a repository\"));\n-\t\tcheck_index = 1;\n+\t\tstate.check_index = 1;\n \t}\n-\tif (check_index)\n+\tif (state.check_index)\n \t\tunsafe_paths = 0;\n \n \tfor (i = 0; i < argc; i++) {\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280434","messageId":"1457545756-20616-12-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 11/48] builtin/apply: move 'apply_in_reverse' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:39Z","receivedAt":"2016-03-09T17:48:39Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 51 ++++++++++++++++++++++++++++++++-------------------\n 1 file changed, 32 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 9bc01a8..6bf3024 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -26,6 +26,8 @@ struct apply_state {\n \tint prefix_length;\n \tint newfd;\n \n+\tint apply_in_reverse;\n+\n \t/*\n \t *  --check turns on checking that the working tree matches the\n \t *    files that are being modified, but doesn't apply the patch\n@@ -53,7 +55,6 @@ static int diffstat;\n static int numstat;\n static int summary;\n static int apply = 1;\n-static int apply_in_reverse;\n static int apply_with_reject;\n static int apply_verbosely;\n static int allow_overlap;\n@@ -1570,8 +1571,11 @@ static void check_whitespace(const char *line, int len, unsigned ws_rule)\n  * between a \"---\" that is part of a patch, and a \"---\" that starts\n  * the next patch is to look at the line counts..\n  */\n-static int parse_fragment(const char *line, unsigned long size,\n-\t\t\t  struct patch *patch, struct fragment *fragment)\n+static int parse_fragment(struct apply_state *state,\n+\t\t\t  const char *line,\n+\t\t\t  unsigned long size,\n+\t\t\t  struct patch *patch,\n+\t\t\t  struct fragment *fragment)\n {\n \tint added, deleted;\n \tint len = linelen(line, size), offset;\n@@ -1611,12 +1615,12 @@ static int parse_fragment(const char *line, unsigned long size,\n \t\t\tif (!deleted && !added)\n \t\t\t\tleading++;\n \t\t\ttrailing++;\n-\t\t\tif (!apply_in_reverse &&\n+\t\t\tif (!state->apply_in_reverse &&\n \t\t\t    ws_error_action == correct_ws_error)\n \t\t\t\tcheck_whitespace(line, len, patch->ws_rule);\n \t\t\tbreak;\n \t\tcase '-':\n-\t\t\tif (apply_in_reverse &&\n+\t\t\tif (state->apply_in_reverse &&\n \t\t\t    ws_error_action != nowarn_ws_error)\n \t\t\t\tcheck_whitespace(line, len, patch->ws_rule);\n \t\t\tdeleted++;\n@@ -1624,7 +1628,7 @@ static int parse_fragment(const char *line, unsigned long size,\n \t\t\ttrailing = 0;\n \t\t\tbreak;\n \t\tcase '+':\n-\t\t\tif (!apply_in_reverse &&\n+\t\t\tif (!state->apply_in_reverse &&\n \t\t\t    ws_error_action != nowarn_ws_error)\n \t\t\t\tcheck_whitespace(line, len, patch->ws_rule);\n \t\t\tadded++;\n@@ -1680,7 +1684,10 @@ static int parse_fragment(const char *line, unsigned long size,\n  * The (fragment->patch, fragment->size) pair points into the memory given\n  * by the caller, not a copy, when we return.\n  */\n-static int parse_single_patch(const char *line, unsigned long size, struct patch *patch)\n+static int parse_single_patch(struct apply_state *state,\n+\t\t\t      const char *line,\n+\t\t\t      unsigned long size,\n+\t\t\t      struct patch *patch)\n {\n \tunsigned long offset = 0;\n \tunsigned long oldlines = 0, newlines = 0, context = 0;\n@@ -1692,7 +1699,7 @@ static int parse_single_patch(const char *line, unsigned long size, struct patch\n \n \t\tfragment = xcalloc(1, sizeof(*fragment));\n \t\tfragment->linenr = linenr;\n-\t\tlen = parse_fragment(line, size, patch, fragment);\n+\t\tlen = parse_fragment(state, line, size, patch, fragment);\n \t\tif (len <= 0)\n \t\t\tdie(_(\"corrupt patch at line %d\"), linenr);\n \t\tfragment->patch = line;\n@@ -2017,8 +2024,10 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\t\t\t\t\t ? patch->new_name\n \t\t\t\t\t\t : patch->old_name);\n \n-\tpatchsize = parse_single_patch(buffer + offset + hdrsize,\n-\t\t\t\t       size - offset - hdrsize, patch);\n+\tpatchsize = parse_single_patch(state,\n+\t\t\t\t       buffer + offset + hdrsize,\n+\t\t\t\t       size - offset - hdrsize,\n+\t\t\t\t       patch);\n \n \tif (!patchsize) {\n \t\tstatic const char git_binary[] = \"GIT binary patch\\n\";\n@@ -2749,7 +2758,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\tif (len < size && patch[len] == '\\\\')\n \t\t\tplen--;\n \t\tfirst = *patch;\n-\t\tif (apply_in_reverse) {\n+\t\tif (state->apply_in_reverse) {\n \t\t\tif (first == '-')\n \t\t\t\tfirst = '+';\n \t\t\telse if (first == '+')\n@@ -2922,7 +2931,7 @@ static int apply_one_fragment(struct apply_state *state,\n \n \t\tif (apply_verbosely && applied_pos != pos) {\n \t\t\tint offset = applied_pos - pos;\n-\t\t\tif (apply_in_reverse)\n+\t\t\tif (state->apply_in_reverse)\n \t\t\t\toffset = 0 - offset;\n \t\t\tfprintf_ln(stderr,\n \t\t\t\t   Q_(\"Hunk #%d succeeded at %d (offset %d line).\",\n@@ -2956,7 +2965,9 @@ out:\n \treturn (applied_pos < 0);\n }\n \n-static int apply_binary_fragment(struct image *img, struct patch *patch)\n+static int apply_binary_fragment(struct apply_state *state,\n+\t\t\t\t struct image *img,\n+\t\t\t\t struct patch *patch)\n {\n \tstruct fragment *fragment = patch->fragments;\n \tunsigned long len;\n@@ -2969,7 +2980,7 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)\n \t\t\t     patch->old_name);\n \n \t/* Binary patch is irreversible without the optional second hunk */\n-\tif (apply_in_reverse) {\n+\tif (state->apply_in_reverse) {\n \t\tif (!fragment->next)\n \t\t\treturn error(\"cannot reverse-apply a binary patch \"\n \t\t\t\t     \"without the reverse hunk to '%s'\",\n@@ -3002,7 +3013,9 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)\n  * but the preimage prepared by the caller in \"img\" is freed here\n  * or in the helper function apply_binary_fragment() this calls.\n  */\n-static int apply_binary(struct image *img, struct patch *patch)\n+static int apply_binary(struct apply_state *state,\n+\t\t\tstruct image *img,\n+\t\t\tstruct patch *patch)\n {\n \tconst char *name = patch->old_name ? patch->old_name : patch->new_name;\n \tunsigned char sha1[20];\n@@ -3063,7 +3076,7 @@ static int apply_binary(struct image *img, struct patch *patch)\n \t\t * apply the patch data to it, which is stored\n \t\t * in the patch->fragments->{patch,size}.\n \t\t */\n-\t\tif (apply_binary_fragment(img, patch))\n+\t\tif (apply_binary_fragment(state, img, patch))\n \t\t\treturn error(_(\"binary patch does not apply to '%s'\"),\n \t\t\t\t     name);\n \n@@ -3086,7 +3099,7 @@ static int apply_fragments(struct apply_state *state, struct image *img, struct\n \tint nth = 0;\n \n \tif (patch->is_binary)\n-\t\treturn apply_binary(img, patch);\n+\t\treturn apply_binary(state, img, patch);\n \n \twhile (frag) {\n \t\tnth++;\n@@ -4423,7 +4436,7 @@ static int apply_patch(struct apply_state *state,\n \t\tnr = parse_chunk(state, buf.buf + offset, buf.len - offset, patch);\n \t\tif (nr < 0)\n \t\t\tbreak;\n-\t\tif (apply_in_reverse)\n+\t\tif (state->apply_in_reverse)\n \t\t\treverse_patches(patch);\n \t\tif (use_patch(state, patch)) {\n \t\t\tpatch_stats(patch);\n@@ -4600,7 +4613,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t{ OPTION_CALLBACK, 0, \"ignore-whitespace\", NULL, NULL,\n \t\t\tN_(\"ignore changes in whitespace when finding context\"),\n \t\t\tPARSE_OPT_NOARG, option_parse_space_change },\n-\t\tOPT_BOOL('R', \"reverse\", &apply_in_reverse,\n+\t\tOPT_BOOL('R', \"reverse\", &state.apply_in_reverse,\n \t\t\tN_(\"apply the patch in reverse\")),\n \t\tOPT_BOOL(0, \"unidiff-zero\", &state.unidiff_zero,\n \t\t\tN_(\"don't expect at least one line of context\")),\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280432","messageId":"1457545756-20616-13-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 12/48] builtin/apply: move 'apply_with_reject' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:40Z","receivedAt":"2016-03-09T17:48:40Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 14 +++++++-------\n 1 file changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 6bf3024..fcb3c14 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -27,6 +27,7 @@ struct apply_state {\n \tint newfd;\n \n \tint apply_in_reverse;\n+\tint apply_with_reject;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -55,7 +56,6 @@ static int diffstat;\n static int numstat;\n static int summary;\n static int apply = 1;\n-static int apply_with_reject;\n static int apply_verbosely;\n static int allow_overlap;\n static int no_add;\n@@ -3105,7 +3105,7 @@ static int apply_fragments(struct apply_state *state, struct image *img, struct\n \t\tnth++;\n \t\tif (apply_one_fragment(state, img, frag, inaccurate_eof, ws_rule, nth)) {\n \t\t\terror(_(\"patch failed: %s:%ld\"), name, frag->oldpos);\n-\t\t\tif (!apply_with_reject)\n+\t\t\tif (!state->apply_with_reject)\n \t\t\t\treturn -1;\n \t\t\tfrag->rejected = 1;\n \t\t}\n@@ -4467,11 +4467,11 @@ static int apply_patch(struct apply_state *state,\n \n \tif ((state->check || apply) &&\n \t    check_patch_list(state, list) < 0 &&\n-\t    !apply_with_reject)\n+\t    !state->apply_with_reject)\n \t\texit(1);\n \n \tif (apply && write_out_results(list)) {\n-\t\tif (apply_with_reject)\n+\t\tif (state->apply_with_reject)\n \t\t\texit(1);\n \t\t/* with --3way, we still need to write the index out */\n \t\treturn 1;\n@@ -4617,7 +4617,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"apply the patch in reverse\")),\n \t\tOPT_BOOL(0, \"unidiff-zero\", &state.unidiff_zero,\n \t\t\tN_(\"don't expect at least one line of context\")),\n-\t\tOPT_BOOL(0, \"reject\", &apply_with_reject,\n+\t\tOPT_BOOL(0, \"reject\", &state.apply_with_reject,\n \t\t\tN_(\"leave the rejected hunks in corresponding *.rej files\")),\n \t\tOPT_BOOL(0, \"allow-overlap\", &allow_overlap,\n \t\t\tN_(\"allow overlapping hunks\")),\n@@ -4648,7 +4648,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n \n-\tif (apply_with_reject && threeway)\n+\tif (state.apply_with_reject && threeway)\n \t\tdie(\"--reject and --3way cannot be used together.\");\n \tif (cached && threeway)\n \t\tdie(\"--cached and --3way cannot be used together.\");\n@@ -4657,7 +4657,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tdie(_(\"--3way outside a repository\"));\n \t\tstate.check_index = 1;\n \t}\n-\tif (apply_with_reject)\n+\tif (state.apply_with_reject)\n \t\tapply = apply_verbosely = 1;\n \tif (!force_apply && (diffstat || numstat || summary || state.check || fake_ancestor))\n \t\tapply = 0;\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280438","messageId":"1457545756-20616-14-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 13/48] builtin/apply: move 'apply_verbosely' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:41Z","receivedAt":"2016-03-09T17:48:41Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 24 ++++++++++++------------\n 1 file changed, 12 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex fcb3c14..4e0737c 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -28,6 +28,7 @@ struct apply_state {\n \n \tint apply_in_reverse;\n \tint apply_with_reject;\n+\tint apply_verbosely;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -56,7 +57,6 @@ static int diffstat;\n static int numstat;\n static int summary;\n static int apply = 1;\n-static int apply_verbosely;\n static int allow_overlap;\n static int no_add;\n static int threeway;\n@@ -2814,7 +2814,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\t/* Ignore it, we already handled it */\n \t\t\tbreak;\n \t\tdefault:\n-\t\t\tif (apply_verbosely)\n+\t\t\tif (state->apply_verbosely)\n \t\t\t\terror(_(\"invalid start of line: '%c'\"), first);\n \t\t\tapplied_pos = -1;\n \t\t\tgoto out;\n@@ -2929,7 +2929,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\t\tapply = 0;\n \t\t}\n \n-\t\tif (apply_verbosely && applied_pos != pos) {\n+\t\tif (state->apply_verbosely && applied_pos != pos) {\n \t\t\tint offset = applied_pos - pos;\n \t\t\tif (state->apply_in_reverse)\n \t\t\t\toffset = 0 - offset;\n@@ -2951,7 +2951,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\t\t   leading, trailing, applied_pos+1);\n \t\tupdate_image(img, applied_pos, &preimage, &postimage);\n \t} else {\n-\t\tif (apply_verbosely)\n+\t\tif (state->apply_verbosely)\n \t\t\terror(_(\"while searching for:\\n%.*s\"),\n \t\t\t      (int)(old - oldlines), oldlines);\n \t}\n@@ -3865,7 +3865,7 @@ static int check_patch_list(struct apply_state *state, struct patch *patch)\n \tprepare_symlink_changes(patch);\n \tprepare_fn_table(patch);\n \twhile (patch) {\n-\t\tif (apply_verbosely)\n+\t\tif (state->apply_verbosely)\n \t\t\tsay_patch_name(stderr,\n \t\t\t\t       _(\"Checking patch %s...\"), patch);\n \t\terr |= check_patch(state, patch);\n@@ -4296,7 +4296,7 @@ static void write_out_one_result(struct patch *patch, int phase)\n \t\tcreate_file(patch);\n }\n \n-static int write_out_one_reject(struct patch *patch)\n+static int write_out_one_reject(struct apply_state *state, struct patch *patch)\n {\n \tFILE *rej;\n \tchar namebuf[PATH_MAX];\n@@ -4311,7 +4311,7 @@ static int write_out_one_reject(struct patch *patch)\n \t}\n \n \tif (!cnt) {\n-\t\tif (apply_verbosely)\n+\t\tif (state->apply_verbosely)\n \t\t\tsay_patch_name(stderr,\n \t\t\t\t       _(\"Applied patch %s cleanly.\"), patch);\n \t\treturn 0;\n@@ -4367,7 +4367,7 @@ static int write_out_one_reject(struct patch *patch)\n \treturn -1;\n }\n \n-static int write_out_results(struct patch *list)\n+static int write_out_results(struct apply_state *state, struct patch *list)\n {\n \tint phase;\n \tint errs = 0;\n@@ -4382,7 +4382,7 @@ static int write_out_results(struct patch *list)\n \t\t\telse {\n \t\t\t\twrite_out_one_result(l, phase);\n \t\t\t\tif (phase == 1) {\n-\t\t\t\t\tif (write_out_one_reject(l))\n+\t\t\t\t\tif (write_out_one_reject(state, l))\n \t\t\t\t\t\terrs = 1;\n \t\t\t\t\tif (l->conflicted_threeway) {\n \t\t\t\t\t\tstring_list_append(&cpath, l->new_name);\n@@ -4470,7 +4470,7 @@ static int apply_patch(struct apply_state *state,\n \t    !state->apply_with_reject)\n \t\texit(1);\n \n-\tif (apply && write_out_results(list)) {\n+\tif (apply && write_out_results(state, list)) {\n \t\tif (state->apply_with_reject)\n \t\t\texit(1);\n \t\t/* with --3way, we still need to write the index out */\n@@ -4621,7 +4621,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"leave the rejected hunks in corresponding *.rej files\")),\n \t\tOPT_BOOL(0, \"allow-overlap\", &allow_overlap,\n \t\t\tN_(\"allow overlapping hunks\")),\n-\t\tOPT__VERBOSE(&apply_verbosely, N_(\"be verbose\")),\n+\t\tOPT__VERBOSE(&state.apply_verbosely, N_(\"be verbose\")),\n \t\tOPT_BIT(0, \"inaccurate-eof\", &options,\n \t\t\tN_(\"tolerate incorrectly detected missing new-line at the end of file\"),\n \t\t\tINACCURATE_EOF),\n@@ -4658,7 +4658,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tstate.check_index = 1;\n \t}\n \tif (state.apply_with_reject)\n-\t\tapply = apply_verbosely = 1;\n+\t\tapply = state.apply_verbosely = 1;\n \tif (!force_apply && (diffstat || numstat || summary || state.check || fake_ancestor))\n \t\tapply = 0;\n \tif (state.check_index && is_not_gitdir)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280436","messageId":"1457545756-20616-15-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 14/48] builtin/apply: move 'update_index' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:42Z","receivedAt":"2016-03-09T17:48:42Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 46 +++++++++++++++++++++++++++-------------------\n 1 file changed, 27 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 4e0737c..a6026cc 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -40,6 +40,8 @@ struct apply_state {\n \tint check_index;\n \n \tint unidiff_zero;\n+\n+\tint update_index;\n };\n \n /*\n@@ -51,7 +53,6 @@ struct apply_state {\n \n static int p_value = 1;\n static int p_value_known;\n-static int update_index;\n static int cached;\n static int diffstat;\n static int numstat;\n@@ -4099,9 +4100,9 @@ static void patch_stats(struct patch *patch)\n \t}\n }\n \n-static void remove_file(struct patch *patch, int rmdir_empty)\n+static void remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)\n {\n-\tif (update_index) {\n+\tif (state->update_index) {\n \t\tif (remove_file_from_cache(patch->old_name) < 0)\n \t\t\tdie(_(\"unable to remove %s from index\"), patch->old_name);\n \t}\n@@ -4112,14 +4113,18 @@ static void remove_file(struct patch *patch, int rmdir_empty)\n \t}\n }\n \n-static void add_index_file(const char *path, unsigned mode, void *buf, unsigned long size)\n+static void add_index_file(struct apply_state *state,\n+\t\t\t   const char *path,\n+\t\t\t   unsigned mode,\n+\t\t\t   void *buf,\n+\t\t\t   unsigned long size)\n {\n \tstruct stat st;\n \tstruct cache_entry *ce;\n \tint namelen = strlen(path);\n \tunsigned ce_size = cache_entry_size(namelen);\n \n-\tif (!update_index)\n+\tif (!state->update_index)\n \t\treturn;\n \n \tce = xcalloc(1, ce_size);\n@@ -4229,13 +4234,14 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned\n \tdie_errno(_(\"unable to write file '%s' mode %o\"), path, mode);\n }\n \n-static void add_conflicted_stages_file(struct patch *patch)\n+static void add_conflicted_stages_file(struct apply_state *state,\n+\t\t\t\t       struct patch *patch)\n {\n \tint stage, namelen;\n \tunsigned ce_size, mode;\n \tstruct cache_entry *ce;\n \n-\tif (!update_index)\n+\tif (!state->update_index)\n \t\treturn;\n \tnamelen = strlen(patch->new_name);\n \tce_size = cache_entry_size(namelen);\n@@ -4256,7 +4262,7 @@ static void add_conflicted_stages_file(struct patch *patch)\n \t}\n }\n \n-static void create_file(struct patch *patch)\n+static void create_file(struct apply_state *state, struct patch *patch)\n {\n \tchar *path = patch->new_name;\n \tunsigned mode = patch->new_mode;\n@@ -4268,22 +4274,24 @@ static void create_file(struct patch *patch)\n \tcreate_one_file(path, mode, buf, size);\n \n \tif (patch->conflicted_threeway)\n-\t\tadd_conflicted_stages_file(patch);\n+\t\tadd_conflicted_stages_file(state, patch);\n \telse\n-\t\tadd_index_file(path, mode, buf, size);\n+\t\tadd_index_file(state, path, mode, buf, size);\n }\n \n /* phase zero is to remove, phase one is to create */\n-static void write_out_one_result(struct patch *patch, int phase)\n+static void write_out_one_result(struct apply_state *state,\n+\t\t\t\t struct patch *patch,\n+\t\t\t\t int phase)\n {\n \tif (patch->is_delete > 0) {\n \t\tif (phase == 0)\n-\t\t\tremove_file(patch, 1);\n+\t\t\tremove_file(state, patch, 1);\n \t\treturn;\n \t}\n \tif (patch->is_new > 0 || patch->is_copy) {\n \t\tif (phase == 1)\n-\t\t\tcreate_file(patch);\n+\t\t\tcreate_file(state, patch);\n \t\treturn;\n \t}\n \t/*\n@@ -4291,9 +4299,9 @@ static void write_out_one_result(struct patch *patch, int phase)\n \t * thing: remove the old, write the new\n \t */\n \tif (phase == 0)\n-\t\tremove_file(patch, patch->is_rename);\n+\t\tremove_file(state, patch, patch->is_rename);\n \tif (phase == 1)\n-\t\tcreate_file(patch);\n+\t\tcreate_file(state, patch);\n }\n \n static int write_out_one_reject(struct apply_state *state, struct patch *patch)\n@@ -4380,7 +4388,7 @@ static int write_out_results(struct apply_state *state, struct patch *list)\n \t\t\tif (l->rejected)\n \t\t\t\terrs = 1;\n \t\t\telse {\n-\t\t\t\twrite_out_one_result(l, phase);\n+\t\t\t\twrite_out_one_result(state, l, phase);\n \t\t\t\tif (phase == 1) {\n \t\t\t\t\tif (write_out_one_reject(state, l))\n \t\t\t\t\t\terrs = 1;\n@@ -4456,8 +4464,8 @@ static int apply_patch(struct apply_state *state,\n \tif (whitespace_error && (ws_error_action == die_on_ws_error))\n \t\tapply = 0;\n \n-\tupdate_index = state->check_index && apply;\n-\tif (update_index && state->newfd < 0)\n+\tstate->update_index = state->check_index && apply;\n+\tif (state->update_index && state->newfd < 0)\n \t\tstate->newfd = hold_locked_index(&lock_file, 1);\n \n \tif (state->check_index) {\n@@ -4722,7 +4730,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\t\twhitespace_error);\n \t}\n \n-\tif (update_index) {\n+\tif (state.update_index) {\n \t\tif (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n \t\t\tdie(_(\"Unable to write new index file\"));\n \t}\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280439","messageId":"1457545756-20616-16-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 15/48] builtin/apply: move 'allow_overlap' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:43Z","receivedAt":"2016-03-09T17:48:43Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 11 ++++++-----\n 1 file changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex a6026cc..e3ca5c9 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -26,6 +26,7 @@ struct apply_state {\n \tint prefix_length;\n \tint newfd;\n \n+\tint allow_overlap;\n \tint apply_in_reverse;\n \tint apply_with_reject;\n \tint apply_verbosely;\n@@ -58,7 +59,6 @@ static int diffstat;\n static int numstat;\n static int summary;\n static int apply = 1;\n-static int allow_overlap;\n static int no_add;\n static int threeway;\n static int unsafe_paths;\n@@ -2637,7 +2637,8 @@ static void remove_last_line(struct image *img)\n  * apply at applied_pos (counts in line numbers) in \"img\".\n  * Update \"img\" to remove \"preimage\" and replace it with \"postimage\".\n  */\n-static void update_image(struct image *img,\n+static void update_image(struct apply_state *state,\n+\t\t\t struct image *img,\n \t\t\t int applied_pos,\n \t\t\t struct image *preimage,\n \t\t\t struct image *postimage)\n@@ -2702,7 +2703,7 @@ static void update_image(struct image *img,\n \tmemcpy(img->line + applied_pos,\n \t       postimage->line,\n \t       postimage->nr * sizeof(*img->line));\n-\tif (!allow_overlap)\n+\tif (!state->allow_overlap)\n \t\tfor (i = 0; i < postimage->nr; i++)\n \t\t\timg->line[applied_pos + i].flag |= LINE_PATCHED;\n \timg->nr = nr;\n@@ -2950,7 +2951,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\tfprintf_ln(stderr, _(\"Context reduced to (%ld/%ld)\"\n \t\t\t\t\t     \" to apply fragment at %d\"),\n \t\t\t\t   leading, trailing, applied_pos+1);\n-\t\tupdate_image(img, applied_pos, &preimage, &postimage);\n+\t\tupdate_image(state, img, applied_pos, &preimage, &postimage);\n \t} else {\n \t\tif (state->apply_verbosely)\n \t\t\terror(_(\"while searching for:\\n%.*s\"),\n@@ -4627,7 +4628,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"don't expect at least one line of context\")),\n \t\tOPT_BOOL(0, \"reject\", &state.apply_with_reject,\n \t\t\tN_(\"leave the rejected hunks in corresponding *.rej files\")),\n-\t\tOPT_BOOL(0, \"allow-overlap\", &allow_overlap,\n+\t\tOPT_BOOL(0, \"allow-overlap\", &state.allow_overlap,\n \t\t\tN_(\"allow overlapping hunks\")),\n \t\tOPT__VERBOSE(&state.apply_verbosely, N_(\"be verbose\")),\n \t\tOPT_BIT(0, \"inaccurate-eof\", &options,\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280437","messageId":"1457545756-20616-17-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 16/48] builtin/apply: move 'cached' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:44Z","receivedAt":"2016-03-09T17:48:44Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 37 +++++++++++++++++++++----------------\n 1 file changed, 21 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex e3ca5c9..85aa817 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -31,6 +31,9 @@ struct apply_state {\n \tint apply_with_reject;\n \tint apply_verbosely;\n \n+\t/* --cached updates only the cache without ever touching the working tree. */\n+\tint cached;\n+\n \t/*\n \t *  --check turns on checking that the working tree matches the\n \t *    files that are being modified, but doesn't apply the patch\n@@ -49,12 +52,10 @@ struct apply_state {\n  *  --stat does just a diffstat, and doesn't actually apply\n  *  --numstat does numeric diffstat, and doesn't actually apply\n  *  --index-info shows the old and new index info for paths if available.\n- *  --cached updates only the cache without ever touching the working tree.\n  */\n \n static int p_value = 1;\n static int p_value_known;\n-static int cached;\n static int diffstat;\n static int numstat;\n static int summary;\n@@ -3274,7 +3275,7 @@ static int load_patch_target(struct apply_state *state,\n \t\t\t     const char *name,\n \t\t\t     unsigned expected_mode)\n {\n-\tif (cached || state->check_index) {\n+\tif (state->cached || state->check_index) {\n \t\tif (read_file_or_gitlink(ce, buf))\n \t\t\treturn error(_(\"read of %s failed\"), name);\n \t} else if (name) {\n@@ -3547,7 +3548,7 @@ static int check_preimage(struct apply_state *state,\n \t\treturn error(_(\"path %s has been renamed/deleted\"), old_name);\n \tif (previous) {\n \t\tst_mode = previous->new_mode;\n-\t} else if (!cached) {\n+\t} else if (!state->cached) {\n \t\tstat_ret = lstat(old_name, st);\n \t\tif (stat_ret && errno != ENOENT)\n \t\t\treturn error(_(\"%s: %s\"), old_name, strerror(errno));\n@@ -3565,9 +3566,9 @@ static int check_preimage(struct apply_state *state,\n \t\t\tif (checkout_target(&the_index, *ce, st))\n \t\t\t\treturn -1;\n \t\t}\n-\t\tif (!cached && verify_index_match(*ce, st))\n+\t\tif (!state->cached && verify_index_match(*ce, st))\n \t\t\treturn error(_(\"%s: does not match index\"), old_name);\n-\t\tif (cached)\n+\t\tif (state->cached)\n \t\t\tst_mode = (*ce)->ce_mode;\n \t} else if (stat_ret < 0) {\n \t\tif (patch->is_new < 0)\n@@ -3575,7 +3576,7 @@ static int check_preimage(struct apply_state *state,\n \t\treturn error(_(\"%s: %s\"), old_name, strerror(errno));\n \t}\n \n-\tif (!cached && !previous)\n+\tif (!state->cached && !previous)\n \t\tst_mode = ce_mode_from_stat(*ce, st->st_mode);\n \n \tif (patch->is_new < 0)\n@@ -3613,7 +3614,7 @@ static int check_to_create(struct apply_state *state,\n \t    cache_name_pos(new_name, strlen(new_name)) >= 0 &&\n \t    !ok_if_exists)\n \t\treturn EXISTS_IN_INDEX;\n-\tif (cached)\n+\tif (state->cached)\n \t\treturn 0;\n \n \tif (!lstat(new_name, &nst)) {\n@@ -4107,7 +4108,7 @@ static void remove_file(struct apply_state *state, struct patch *patch, int rmdi\n \t\tif (remove_file_from_cache(patch->old_name) < 0)\n \t\t\tdie(_(\"unable to remove %s from index\"), patch->old_name);\n \t}\n-\tif (!cached) {\n+\tif (!state->cached) {\n \t\tif (!remove_or_warn(patch->old_mode, patch->old_name) && rmdir_empty) {\n \t\t\tremove_path(patch->old_name);\n \t\t}\n@@ -4140,7 +4141,7 @@ static void add_index_file(struct apply_state *state,\n \t\t    get_sha1_hex(s, ce->sha1))\n \t\t\tdie(_(\"corrupt patch for submodule %s\"), path);\n \t} else {\n-\t\tif (!cached) {\n+\t\tif (!state->cached) {\n \t\t\tif (lstat(path, &st) < 0)\n \t\t\t\tdie_errno(_(\"unable to stat newly created file '%s'\"),\n \t\t\t\t\t  path);\n@@ -4192,9 +4193,13 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,\n  * which is true 99% of the time anyway. If they don't,\n  * we create them and try again.\n  */\n-static void create_one_file(char *path, unsigned mode, const char *buf, unsigned long size)\n+static void create_one_file(struct apply_state *state,\n+\t\t\t    char *path,\n+\t\t\t    unsigned mode,\n+\t\t\t    const char *buf,\n+\t\t\t    unsigned long size)\n {\n-\tif (cached)\n+\tif (state->cached)\n \t\treturn;\n \tif (!try_create_file(path, mode, buf, size))\n \t\treturn;\n@@ -4272,7 +4277,7 @@ static void create_file(struct apply_state *state, struct patch *patch)\n \n \tif (!mode)\n \t\tmode = S_IFREG | 0644;\n-\tcreate_one_file(path, mode, buf, size);\n+\tcreate_one_file(state, path, mode, buf, size);\n \n \tif (patch->conflicted_threeway)\n \t\tadd_conflicted_stages_file(state, patch);\n@@ -4598,7 +4603,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"instead of applying the patch, see if the patch is applicable\")),\n \t\tOPT_BOOL(0, \"index\", &state.check_index,\n \t\t\tN_(\"make sure the patch is applicable to the current index\")),\n-\t\tOPT_BOOL(0, \"cached\", &cached,\n+\t\tOPT_BOOL(0, \"cached\", &state.cached,\n \t\t\tN_(\"apply a patch without touching the working tree\")),\n \t\tOPT_BOOL(0, \"unsafe-paths\", &unsafe_paths,\n \t\t\tN_(\"accept a patch that touches outside the working area\")),\n@@ -4659,7 +4664,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \n \tif (state.apply_with_reject && threeway)\n \t\tdie(\"--reject and --3way cannot be used together.\");\n-\tif (cached && threeway)\n+\tif (state.cached && threeway)\n \t\tdie(\"--cached and --3way cannot be used together.\");\n \tif (threeway) {\n \t\tif (is_not_gitdir)\n@@ -4672,7 +4677,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tapply = 0;\n \tif (state.check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n-\tif (cached) {\n+\tif (state.cached) {\n \t\tif (is_not_gitdir)\n \t\t\tdie(_(\"--cached outside a repository\"));\n \t\tstate.check_index = 1;\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280440","messageId":"1457545756-20616-18-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 17/48] builtin/apply: move 'diffstat' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:45Z","receivedAt":"2016-03-09T17:48:45Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 11 ++++++-----\n 1 file changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 85aa817..fd5cb7d 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -34,6 +34,9 @@ struct apply_state {\n \t/* --cached updates only the cache without ever touching the working tree. */\n \tint cached;\n \n+\t/* --stat does just a diffstat, and doesn't actually apply */\n+\tint diffstat;\n+\n \t/*\n \t *  --check turns on checking that the working tree matches the\n \t *    files that are being modified, but doesn't apply the patch\n@@ -49,14 +52,12 @@ struct apply_state {\n };\n \n /*\n- *  --stat does just a diffstat, and doesn't actually apply\n  *  --numstat does numeric diffstat, and doesn't actually apply\n  *  --index-info shows the old and new index info for paths if available.\n  */\n \n static int p_value = 1;\n static int p_value_known;\n-static int diffstat;\n static int numstat;\n static int summary;\n static int apply = 1;\n@@ -4494,7 +4495,7 @@ static int apply_patch(struct apply_state *state,\n \tif (fake_ancestor)\n \t\tbuild_fake_ancestor(list, fake_ancestor);\n \n-\tif (diffstat)\n+\tif (state->diffstat)\n \t\tstat_patch_list(list);\n \n \tif (numstat)\n@@ -4591,7 +4592,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\t0, option_parse_p },\n \t\tOPT_BOOL(0, \"no-add\", &no_add,\n \t\t\tN_(\"ignore additions made by the patch\")),\n-\t\tOPT_BOOL(0, \"stat\", &diffstat,\n+\t\tOPT_BOOL(0, \"stat\", &state.diffstat,\n \t\t\tN_(\"instead of applying the patch, output diffstat for the input\")),\n \t\tOPT_NOOP_NOARG(0, \"allow-binary-replacement\"),\n \t\tOPT_NOOP_NOARG(0, \"binary\"),\n@@ -4673,7 +4674,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t}\n \tif (state.apply_with_reject)\n \t\tapply = state.apply_verbosely = 1;\n-\tif (!force_apply && (diffstat || numstat || summary || state.check || fake_ancestor))\n+\tif (!force_apply && (state.diffstat || numstat || summary || state.check || fake_ancestor))\n \t\tapply = 0;\n \tif (state.check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280441","messageId":"1457545756-20616-19-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 18/48] builtin/apply: move 'numstat' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:46Z","receivedAt":"2016-03-09T17:48:46Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 11 ++++++-----\n 1 file changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex fd5cb7d..0378465 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -37,6 +37,9 @@ struct apply_state {\n \t/* --stat does just a diffstat, and doesn't actually apply */\n \tint diffstat;\n \n+\t/* --numstat does numeric diffstat, and doesn't actually apply */\n+\tint numstat;\n+\n \t/*\n \t *  --check turns on checking that the working tree matches the\n \t *    files that are being modified, but doesn't apply the patch\n@@ -52,13 +55,11 @@ struct apply_state {\n };\n \n /*\n- *  --numstat does numeric diffstat, and doesn't actually apply\n  *  --index-info shows the old and new index info for paths if available.\n  */\n \n static int p_value = 1;\n static int p_value_known;\n-static int numstat;\n static int summary;\n static int apply = 1;\n static int no_add;\n@@ -4498,7 +4499,7 @@ static int apply_patch(struct apply_state *state,\n \tif (state->diffstat)\n \t\tstat_patch_list(list);\n \n-\tif (numstat)\n+\tif (state->numstat)\n \t\tnumstat_patch_list(list);\n \n \tif (summary)\n@@ -4596,7 +4597,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"instead of applying the patch, output diffstat for the input\")),\n \t\tOPT_NOOP_NOARG(0, \"allow-binary-replacement\"),\n \t\tOPT_NOOP_NOARG(0, \"binary\"),\n-\t\tOPT_BOOL(0, \"numstat\", &numstat,\n+\t\tOPT_BOOL(0, \"numstat\", &state.numstat,\n \t\t\tN_(\"show number of added and deleted lines in decimal notation\")),\n \t\tOPT_BOOL(0, \"summary\", &summary,\n \t\t\tN_(\"instead of applying the patch, output a summary for the input\")),\n@@ -4674,7 +4675,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t}\n \tif (state.apply_with_reject)\n \t\tapply = state.apply_verbosely = 1;\n-\tif (!force_apply && (state.diffstat || numstat || summary || state.check || fake_ancestor))\n+\tif (!force_apply && (state.diffstat || state.numstat || summary || state.check || fake_ancestor))\n \t\tapply = 0;\n \tif (state.check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280442","messageId":"1457545756-20616-20-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 19/48] builtin/apply: move 'summary' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:47Z","receivedAt":"2016-03-09T17:48:47Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 9 +++++----\n 1 file changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 0378465..1542dcf 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -40,6 +40,8 @@ struct apply_state {\n \t/* --numstat does numeric diffstat, and doesn't actually apply */\n \tint numstat;\n \n+\tint summary;\n+\n \t/*\n \t *  --check turns on checking that the working tree matches the\n \t *    files that are being modified, but doesn't apply the patch\n@@ -60,7 +62,6 @@ struct apply_state {\n \n static int p_value = 1;\n static int p_value_known;\n-static int summary;\n static int apply = 1;\n static int no_add;\n static int threeway;\n@@ -4502,7 +4503,7 @@ static int apply_patch(struct apply_state *state,\n \tif (state->numstat)\n \t\tnumstat_patch_list(list);\n \n-\tif (summary)\n+\tif (state->summary)\n \t\tsummary_patch_list(list);\n \n \tfree_patch_list(list);\n@@ -4599,7 +4600,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tOPT_NOOP_NOARG(0, \"binary\"),\n \t\tOPT_BOOL(0, \"numstat\", &state.numstat,\n \t\t\tN_(\"show number of added and deleted lines in decimal notation\")),\n-\t\tOPT_BOOL(0, \"summary\", &summary,\n+\t\tOPT_BOOL(0, \"summary\", &state.summary,\n \t\t\tN_(\"instead of applying the patch, output a summary for the input\")),\n \t\tOPT_BOOL(0, \"check\", &state.check,\n \t\t\tN_(\"instead of applying the patch, see if the patch is applicable\")),\n@@ -4675,7 +4676,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t}\n \tif (state.apply_with_reject)\n \t\tapply = state.apply_verbosely = 1;\n-\tif (!force_apply && (state.diffstat || state.numstat || summary || state.check || fake_ancestor))\n+\tif (!force_apply && (state.diffstat || state.numstat || state.summary || state.check || fake_ancestor))\n \t\tapply = 0;\n \tif (state.check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280444","messageId":"1457545756-20616-21-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 20/48] builtin/apply: move 'threeway' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:48Z","receivedAt":"2016-03-09T17:48:48Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 15 ++++++++-------\n 1 file changed, 8 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 1542dcf..fab731f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -42,6 +42,8 @@ struct apply_state {\n \n \tint summary;\n \n+\tint threeway;\n+\n \t/*\n \t *  --check turns on checking that the working tree matches the\n \t *    files that are being modified, but doesn't apply the patch\n@@ -64,7 +66,6 @@ static int p_value = 1;\n static int p_value_known;\n static int apply = 1;\n static int no_add;\n-static int threeway;\n static int unsafe_paths;\n static const char *fake_ancestor;\n static int line_termination = '\\n';\n@@ -3506,7 +3507,7 @@ static int apply_data(struct apply_state *state, struct patch *patch,\n \tif (patch->direct_to_threeway ||\n \t    apply_fragments(state, &image, patch) < 0) {\n \t\t/* Note: with --reject, apply_fragments() returns 0 */\n-\t\tif (!threeway || try_threeway(state, &image, patch, st, ce) < 0)\n+\t\tif (!state->threeway || try_threeway(state, &image, patch, st, ce) < 0)\n \t\t\treturn -1;\n \t}\n \tpatch->result = image.buf;\n@@ -3801,7 +3802,7 @@ static int check_patch(struct apply_state *state, struct patch *patch)\n \t    ((0 < patch->is_new) || patch->is_rename || patch->is_copy)) {\n \t\tint err = check_to_create(state, new_name, ok_if_exists);\n \n-\t\tif (err && threeway) {\n+\t\tif (err && state->threeway) {\n \t\t\tpatch->direct_to_threeway = 1;\n \t\t} else switch (err) {\n \t\tcase 0:\n@@ -4612,7 +4613,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"accept a patch that touches outside the working area\")),\n \t\tOPT_BOOL(0, \"apply\", &force_apply,\n \t\t\tN_(\"also apply the patch (use with --stat/--summary/--check)\")),\n-\t\tOPT_BOOL('3', \"3way\", &threeway,\n+\t\tOPT_BOOL('3', \"3way\", &state.threeway,\n \t\t\t N_( \"attempt three-way merge if a patch does not apply\")),\n \t\tOPT_FILENAME(0, \"build-fake-ancestor\", &fake_ancestor,\n \t\t\tN_(\"build a temporary index based on embedded index information\")),\n@@ -4665,11 +4666,11 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n \n-\tif (state.apply_with_reject && threeway)\n+\tif (state.apply_with_reject && state.threeway)\n \t\tdie(\"--reject and --3way cannot be used together.\");\n-\tif (state.cached && threeway)\n+\tif (state.cached && state.threeway)\n \t\tdie(\"--cached and --3way cannot be used together.\");\n-\tif (threeway) {\n+\tif (state.threeway) {\n \t\tif (is_not_gitdir)\n \t\t\tdie(_(\"--3way outside a repository\"));\n \t\tstate.check_index = 1;\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280445","messageId":"1457545756-20616-22-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 21/48] builtin/apply: move 'no-add' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:49Z","receivedAt":"2016-03-09T17:48:49Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex fab731f..ae734cf 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -44,6 +44,8 @@ struct apply_state {\n \n \tint threeway;\n \n+\tint no_add;\n+\n \t/*\n \t *  --check turns on checking that the working tree matches the\n \t *    files that are being modified, but doesn't apply the patch\n@@ -65,7 +67,6 @@ struct apply_state {\n static int p_value = 1;\n static int p_value_known;\n static int apply = 1;\n-static int no_add;\n static int unsafe_paths;\n static const char *fake_ancestor;\n static int line_termination = '\\n';\n@@ -2798,7 +2799,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t/* Fall-through for ' ' */\n \t\tcase '+':\n \t\t\t/* --no-add does not add new lines */\n-\t\t\tif (first == '+' && no_add)\n+\t\t\tif (first == '+' && state->no_add)\n \t\t\t\tbreak;\n \n \t\t\tstart = newlines.len;\n@@ -4593,7 +4594,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t{ OPTION_CALLBACK, 'p', NULL, NULL, N_(\"num\"),\n \t\t\tN_(\"remove <num> leading slashes from traditional diff paths\"),\n \t\t\t0, option_parse_p },\n-\t\tOPT_BOOL(0, \"no-add\", &no_add,\n+\t\tOPT_BOOL(0, \"no-add\", &state.no_add,\n \t\t\tN_(\"ignore additions made by the patch\")),\n \t\tOPT_BOOL(0, \"stat\", &state.diffstat,\n \t\t\tN_(\"instead of applying the patch, output diffstat for the input\")),\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280443","messageId":"1457545756-20616-23-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 22/48] builtin/apply: move 'unsafe_paths' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:50Z","receivedAt":"2016-03-09T17:48:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 9 +++++----\n 1 file changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex ae734cf..0c2fa2e 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -58,6 +58,8 @@ struct apply_state {\n \tint unidiff_zero;\n \n \tint update_index;\n+\n+\tint unsafe_paths;\n };\n \n /*\n@@ -67,7 +69,6 @@ struct apply_state {\n static int p_value = 1;\n static int p_value_known;\n static int apply = 1;\n-static int unsafe_paths;\n static const char *fake_ancestor;\n static int line_termination = '\\n';\n static unsigned int p_context = UINT_MAX;\n@@ -3844,7 +3845,7 @@ static int check_patch(struct apply_state *state, struct patch *patch)\n \t\t}\n \t}\n \n-\tif (!unsafe_paths)\n+\tif (!state->unsafe_paths)\n \t\tdie_on_unsafe_path(patch);\n \n \t/*\n@@ -4610,7 +4611,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"make sure the patch is applicable to the current index\")),\n \t\tOPT_BOOL(0, \"cached\", &state.cached,\n \t\t\tN_(\"apply a patch without touching the working tree\")),\n-\t\tOPT_BOOL(0, \"unsafe-paths\", &unsafe_paths,\n+\t\tOPT_BOOL(0, \"unsafe-paths\", &state.unsafe_paths,\n \t\t\tN_(\"accept a patch that touches outside the working area\")),\n \t\tOPT_BOOL(0, \"apply\", &force_apply,\n \t\t\tN_(\"also apply the patch (use with --stat/--summary/--check)\")),\n@@ -4688,7 +4689,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tstate.check_index = 1;\n \t}\n \tif (state.check_index)\n-\t\tunsafe_paths = 0;\n+\t\tstate.unsafe_paths = 0;\n \n \tfor (i = 0; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280446","messageId":"1457545756-20616-24-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 23/48] builtin/apply: move 'line_termination' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:51Z","receivedAt":"2016-03-09T17:48:51Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 13 ++++++++-----\n 1 file changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 0c2fa2e..cc90773 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -60,6 +60,8 @@ struct apply_state {\n \tint update_index;\n \n \tint unsafe_paths;\n+\n+\tint line_termination;\n };\n \n /*\n@@ -70,7 +72,6 @@ static int p_value = 1;\n static int p_value_known;\n static int apply = 1;\n static const char *fake_ancestor;\n-static int line_termination = '\\n';\n static unsigned int p_context = UINT_MAX;\n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n@@ -3995,7 +3996,8 @@ static void stat_patch_list(struct patch *patch)\n \tprint_stat_summary(stdout, files, adds, dels);\n }\n \n-static void numstat_patch_list(struct patch *patch)\n+static void numstat_patch_list(struct apply_state *state,\n+\t\t\t       struct patch *patch)\n {\n \tfor ( ; patch; patch = patch->next) {\n \t\tconst char *name;\n@@ -4004,7 +4006,7 @@ static void numstat_patch_list(struct patch *patch)\n \t\t\tprintf(\"-\\t-\\t\");\n \t\telse\n \t\t\tprintf(\"%d\\t%d\\t\", patch->lines_added, patch->lines_deleted);\n-\t\twrite_name_quoted(name, stdout, line_termination);\n+\t\twrite_name_quoted(name, stdout, state->line_termination);\n \t}\n }\n \n@@ -4504,7 +4506,7 @@ static int apply_patch(struct apply_state *state,\n \t\tstat_patch_list(list);\n \n \tif (state->numstat)\n-\t\tnumstat_patch_list(list);\n+\t\tnumstat_patch_list(state, list);\n \n \tif (state->summary)\n \t\tsummary_patch_list(list);\n@@ -4620,7 +4622,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tOPT_FILENAME(0, \"build-fake-ancestor\", &fake_ancestor,\n \t\t\tN_(\"build a temporary index based on embedded index information\")),\n \t\t/* Think twice before adding \"--nul\" synonym to this */\n-\t\tOPT_SET_INT('z', NULL, &line_termination,\n+\t\tOPT_SET_INT('z', NULL, &state.line_termination,\n \t\t\tN_(\"paths are separated with NUL character\"), '\\0'),\n \t\tOPT_INTEGER('C', NULL, &p_context,\n \t\t\t\tN_(\"ensure at least <n> lines of context match\")),\n@@ -4658,6 +4660,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.prefix = prefix_;\n \tstate.prefix_length = state.prefix ? strlen(state.prefix) : 0;\n \tstate.newfd = -1;\n+\tstate.line_termination = '\\n';\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280447","messageId":"1457545756-20616-25-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 24/48] builtin/apply: move 'fake_ancestor' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:52Z","receivedAt":"2016-03-09T17:48:52Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"By the way remove comment about '--index-info' that was renamed\n'--build-fake-ancestor' in commit 26b28007689d27a921ea90e5a29fc8eb74b0d297\n(apply: get rid of --index-info in favor of --build-fake-ancestor,\nSep 17 2007).\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex cc90773..5a2f0f4 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -40,6 +40,8 @@ struct apply_state {\n \t/* --numstat does numeric diffstat, and doesn't actually apply */\n \tint numstat;\n \n+\tconst char *fake_ancestor;\n+\n \tint summary;\n \n \tint threeway;\n@@ -64,14 +66,9 @@ struct apply_state {\n \tint line_termination;\n };\n \n-/*\n- *  --index-info shows the old and new index info for paths if available.\n- */\n-\n static int p_value = 1;\n static int p_value_known;\n static int apply = 1;\n-static const char *fake_ancestor;\n static unsigned int p_context = UINT_MAX;\n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n@@ -4499,8 +4496,8 @@ static int apply_patch(struct apply_state *state,\n \t\treturn 1;\n \t}\n \n-\tif (fake_ancestor)\n-\t\tbuild_fake_ancestor(list, fake_ancestor);\n+\tif (state->fake_ancestor)\n+\t\tbuild_fake_ancestor(list, state->fake_ancestor);\n \n \tif (state->diffstat)\n \t\tstat_patch_list(list);\n@@ -4619,7 +4616,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"also apply the patch (use with --stat/--summary/--check)\")),\n \t\tOPT_BOOL('3', \"3way\", &state.threeway,\n \t\t\t N_( \"attempt three-way merge if a patch does not apply\")),\n-\t\tOPT_FILENAME(0, \"build-fake-ancestor\", &fake_ancestor,\n+\t\tOPT_FILENAME(0, \"build-fake-ancestor\", &state.fake_ancestor,\n \t\t\tN_(\"build a temporary index based on embedded index information\")),\n \t\t/* Think twice before adding \"--nul\" synonym to this */\n \t\tOPT_SET_INT('z', NULL, &state.line_termination,\n@@ -4682,7 +4679,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t}\n \tif (state.apply_with_reject)\n \t\tapply = state.apply_verbosely = 1;\n-\tif (!force_apply && (state.diffstat || state.numstat || state.summary || state.check || fake_ancestor))\n+\tif (!force_apply && (state.diffstat || state.numstat || state.summary || state.check || state.fake_ancestor))\n \t\tapply = 0;\n \tif (state.check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280448","messageId":"1457545756-20616-26-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 25/48] builtin/apply: move 'p_context' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:53Z","receivedAt":"2016-03-09T17:48:53Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 8 +++++---\n 1 file changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 5a2f0f4..6e347e2 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -64,12 +64,13 @@ struct apply_state {\n \tint unsafe_paths;\n \n \tint line_termination;\n+\n+\tunsigned int p_context;\n };\n \n static int p_value = 1;\n static int p_value_known;\n static int apply = 1;\n-static unsigned int p_context = UINT_MAX;\n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n \tNULL\n@@ -2889,7 +2890,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\tbreak;\n \n \t\t/* Am I at my context limits? */\n-\t\tif ((leading <= p_context) && (trailing <= p_context))\n+\t\tif ((leading <= state->p_context) && (trailing <= state->p_context))\n \t\t\tbreak;\n \t\tif (match_beginning || match_end) {\n \t\t\tmatch_beginning = match_end = 0;\n@@ -4621,7 +4622,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t/* Think twice before adding \"--nul\" synonym to this */\n \t\tOPT_SET_INT('z', NULL, &state.line_termination,\n \t\t\tN_(\"paths are separated with NUL character\"), '\\0'),\n-\t\tOPT_INTEGER('C', NULL, &p_context,\n+\t\tOPT_INTEGER('C', NULL, &state.p_context,\n \t\t\t\tN_(\"ensure at least <n> lines of context match\")),\n \t\t{ OPTION_CALLBACK, 0, \"whitespace\", &whitespace_option, N_(\"action\"),\n \t\t\tN_(\"detect new or modified lines that have whitespace errors\"),\n@@ -4658,6 +4659,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.prefix_length = state.prefix ? strlen(state.prefix) : 0;\n \tstate.newfd = -1;\n \tstate.line_termination = '\\n';\n+\tstate.p_context = UINT_MAX;\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280450","messageId":"1457545756-20616-27-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 26/48] builtin/apply: move 'apply' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:54Z","receivedAt":"2016-03-09T17:48:54Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 31 +++++++++++++++++--------------\n 1 file changed, 17 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 6e347e2..6342b61 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -26,6 +26,7 @@ struct apply_state {\n \tint prefix_length;\n \tint newfd;\n \n+\tint apply;\n \tint allow_overlap;\n \tint apply_in_reverse;\n \tint apply_with_reject;\n@@ -70,7 +71,7 @@ struct apply_state {\n \n static int p_value = 1;\n static int p_value_known;\n-static int apply = 1;\n+\n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n \tNULL\n@@ -141,10 +142,11 @@ static void parse_ignorewhitespace_option(const char *option)\n \tdie(_(\"unrecognized whitespace ignore option '%s'\"), option);\n }\n \n-static void set_default_whitespace_mode(const char *whitespace_option)\n+static void set_default_whitespace_mode(struct apply_state *state,\n+\t\t\t\t\tconst char *whitespace_option)\n {\n \tif (!whitespace_option && !apply_default_whitespace)\n-\t\tws_error_action = (apply ? warn_on_ws_error : nowarn_ws_error);\n+\t\tws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);\n }\n \n /*\n@@ -2075,7 +2077,7 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\t * without metadata change.  A binary patch appears\n \t\t * empty to us here.\n \t\t */\n-\t\tif ((apply || state->check) &&\n+\t\tif ((state->apply || state->check) &&\n \t\t    (!patch->is_binary && !metadata_changes(patch)))\n \t\t\tdie(_(\"patch with only garbage at line %d\"), linenr);\n \t}\n@@ -2934,7 +2936,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\t * apply_data->apply_fragments->apply_one_fragment\n \t\t\t */\n \t\t\tif (ws_error_action == die_on_ws_error)\n-\t\t\t\tapply = 0;\n+\t\t\t\tstate->apply = 0;\n \t\t}\n \n \t\tif (state->apply_verbosely && applied_pos != pos) {\n@@ -4474,9 +4476,9 @@ static int apply_patch(struct apply_state *state,\n \t\tdie(_(\"unrecognized input\"));\n \n \tif (whitespace_error && (ws_error_action == die_on_ws_error))\n-\t\tapply = 0;\n+\t\tstate->apply = 0;\n \n-\tstate->update_index = state->check_index && apply;\n+\tstate->update_index = state->check_index && state->apply;\n \tif (state->update_index && state->newfd < 0)\n \t\tstate->newfd = hold_locked_index(&lock_file, 1);\n \n@@ -4485,12 +4487,12 @@ static int apply_patch(struct apply_state *state,\n \t\t\tdie(_(\"unable to read index file\"));\n \t}\n \n-\tif ((state->check || apply) &&\n+\tif ((state->check || state->apply) &&\n \t    check_patch_list(state, list) < 0 &&\n \t    !state->apply_with_reject)\n \t\texit(1);\n \n-\tif (apply && write_out_results(state, list)) {\n+\tif (state->apply && write_out_results(state, list)) {\n \t\tif (state->apply_with_reject)\n \t\t\texit(1);\n \t\t/* with --3way, we still need to write the index out */\n@@ -4657,6 +4659,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tmemset(&state, 0, sizeof(state));\n \tstate.prefix = prefix_;\n \tstate.prefix_length = state.prefix ? strlen(state.prefix) : 0;\n+\tstate.apply = 1;\n \tstate.newfd = -1;\n \tstate.line_termination = '\\n';\n \tstate.p_context = UINT_MAX;\n@@ -4680,9 +4683,9 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tstate.check_index = 1;\n \t}\n \tif (state.apply_with_reject)\n-\t\tapply = state.apply_verbosely = 1;\n+\t\tstate.apply = state.apply_verbosely = 1;\n \tif (!force_apply && (state.diffstat || state.numstat || state.summary || state.check || state.fake_ancestor))\n-\t\tapply = 0;\n+\t\tstate.apply = 0;\n \tif (state.check_index && is_not_gitdir)\n \t\tdie(_(\"--index outside a repository\"));\n \tif (state.cached) {\n@@ -4710,11 +4713,11 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tif (fd < 0)\n \t\t\tdie_errno(_(\"can't open patch '%s'\"), arg);\n \t\tread_stdin = 0;\n-\t\tset_default_whitespace_mode(whitespace_option);\n+\t\tset_default_whitespace_mode(&state, whitespace_option);\n \t\terrs |= apply_patch(&state, fd, arg, options);\n \t\tclose(fd);\n \t}\n-\tset_default_whitespace_mode(whitespace_option);\n+\tset_default_whitespace_mode(&state, whitespace_option);\n \tif (read_stdin)\n \t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n \tif (whitespace_error) {\n@@ -4732,7 +4735,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\t       \"%d lines add whitespace errors.\",\n \t\t\t       whitespace_error),\n \t\t\t    whitespace_error);\n-\t\tif (applied_after_fixing_ws && apply)\n+\t\tif (applied_after_fixing_ws && state.apply)\n \t\t\twarning(\"%d line%s applied after\"\n \t\t\t\t\" fixing whitespace errors.\",\n \t\t\t\tapplied_after_fixing_ws,\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280449","messageId":"1457545756-20616-28-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 27/48] builtin/apply: move 'read_stdin' global into cmd_apply()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:55Z","receivedAt":"2016-03-09T17:48:55Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 6342b61..44fdb9d 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -95,7 +95,6 @@ static enum ws_ignore {\n \n static const char *patch_input_file;\n static struct strbuf root = STRBUF_INIT;\n-static int read_stdin = 1;\n \n static void parse_whitespace_option(const char *option)\n {\n@@ -4583,6 +4582,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tint is_not_gitdir = !startup_info->have_repository;\n \tint force_apply = 0;\n \tint options = 0;\n+\tint read_stdin = 1;\n \tstruct apply_state state;\n \n \tconst char *whitespace_option = NULL;\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280458","messageId":"1457545756-20616-29-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 28/48] builtin/apply: move 'lock_file' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:56Z","receivedAt":"2016-03-09T17:48:56Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 44fdb9d..70bb51a 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -67,6 +67,8 @@ struct apply_state {\n \tint line_termination;\n \n \tunsigned int p_context;\n+\n+\tstruct lock_file lock_file;\n };\n \n static int p_value = 1;\n@@ -4429,8 +4431,6 @@ static int write_out_results(struct apply_state *state, struct patch *list)\n \treturn errs;\n }\n \n-static struct lock_file lock_file;\n-\n #define INACCURATE_EOF\t(1<<0)\n #define RECOUNT\t\t(1<<1)\n \n@@ -4479,7 +4479,7 @@ static int apply_patch(struct apply_state *state,\n \n \tstate->update_index = state->check_index && state->apply;\n \tif (state->update_index && state->newfd < 0)\n-\t\tstate->newfd = hold_locked_index(&lock_file, 1);\n+\t\tstate->newfd = hold_locked_index(&state->lock_file, 1);\n \n \tif (state->check_index) {\n \t\tif (read_cache() < 0)\n@@ -4748,7 +4748,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t}\n \n \tif (state.update_index) {\n-\t\tif (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n+\t\tif (write_locked_index(&the_index, &state.lock_file, COMMIT_LOCK))\n \t\t\tdie(_(\"Unable to write new index file\"));\n \t}\n \n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280451","messageId":"1457545756-20616-30-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 29/48] builtin/apply: move 'patch_input_file' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:57Z","receivedAt":"2016-03-09T17:48:57Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 28 ++++++++++++++++++----------\n 1 file changed, 18 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 70bb51a..e94594d 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -69,6 +69,8 @@ struct apply_state {\n \tunsigned int p_context;\n \n \tstruct lock_file lock_file;\n+\n+\tconst char *patch_input_file;\n };\n \n static int p_value = 1;\n@@ -95,7 +97,6 @@ static enum ws_ignore {\n } ws_ignore_action = ignore_ws_none;\n \n \n-static const char *patch_input_file;\n static struct strbuf root = STRBUF_INIT;\n \n static void parse_whitespace_option(const char *option)\n@@ -1550,7 +1551,11 @@ static int find_header(struct apply_state *state,\n \treturn -1;\n }\n \n-static void record_ws_error(unsigned result, const char *line, int len, int l_nr)\n+static void record_ws_error(struct apply_state *state,\n+\t\t\t    unsigned result,\n+\t\t\t    const char *line,\n+\t\t\t    int len,\n+\t\t\t    int l_nr)\n {\n \tchar *err;\n \n@@ -1564,15 +1569,18 @@ static void record_ws_error(unsigned result, const char *line, int len, int l_nr\n \n \terr = whitespace_error_string(result);\n \tfprintf(stderr, \"%s:%d: %s.\\n%.*s\\n\",\n-\t\tpatch_input_file, l_nr, err, len, line);\n+\t\tstate->patch_input_file, l_nr, err, len, line);\n \tfree(err);\n }\n \n-static void check_whitespace(const char *line, int len, unsigned ws_rule)\n+static void check_whitespace(struct apply_state *state,\n+\t\t\t     const char *line,\n+\t\t\t     int len,\n+\t\t\t     unsigned ws_rule)\n {\n \tunsigned result = ws_check(line + 1, len - 1, ws_rule);\n \n-\trecord_ws_error(result, line + 1, len - 2, linenr);\n+\trecord_ws_error(state, result, line + 1, len - 2, linenr);\n }\n \n /*\n@@ -1627,12 +1635,12 @@ static int parse_fragment(struct apply_state *state,\n \t\t\ttrailing++;\n \t\t\tif (!state->apply_in_reverse &&\n \t\t\t    ws_error_action == correct_ws_error)\n-\t\t\t\tcheck_whitespace(line, len, patch->ws_rule);\n+\t\t\t\tcheck_whitespace(state, line, len, patch->ws_rule);\n \t\t\tbreak;\n \t\tcase '-':\n \t\t\tif (state->apply_in_reverse &&\n \t\t\t    ws_error_action != nowarn_ws_error)\n-\t\t\t\tcheck_whitespace(line, len, patch->ws_rule);\n+\t\t\t\tcheck_whitespace(state, line, len, patch->ws_rule);\n \t\t\tdeleted++;\n \t\t\toldlines--;\n \t\t\ttrailing = 0;\n@@ -1640,7 +1648,7 @@ static int parse_fragment(struct apply_state *state,\n \t\tcase '+':\n \t\t\tif (!state->apply_in_reverse &&\n \t\t\t    ws_error_action != nowarn_ws_error)\n-\t\t\t\tcheck_whitespace(line, len, patch->ws_rule);\n+\t\t\t\tcheck_whitespace(state, line, len, patch->ws_rule);\n \t\t\tadded++;\n \t\t\tnewlines--;\n \t\t\ttrailing = 0;\n@@ -2923,7 +2931,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t    preimage.nr + applied_pos >= img->nr &&\n \t\t    (ws_rule & WS_BLANK_AT_EOF) &&\n \t\t    ws_error_action != nowarn_ws_error) {\n-\t\t\trecord_ws_error(WS_BLANK_AT_EOF, \"+\", 1,\n+\t\t\trecord_ws_error(state, WS_BLANK_AT_EOF, \"+\", 1,\n \t\t\t\t\tfound_new_blank_lines_at_end);\n \t\t\tif (ws_error_action == correct_ws_error) {\n \t\t\t\twhile (new_blank_lines_at_end--)\n@@ -4444,7 +4452,7 @@ static int apply_patch(struct apply_state *state,\n \tstruct patch *list = NULL, **listp = &list;\n \tint skipped_patch = 0;\n \n-\tpatch_input_file = filename;\n+\tstate->patch_input_file = filename;\n \tread_patch_file(&buf, fd);\n \toffset = 0;\n \twhile (offset < buf.len) {\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280452","messageId":"1457545756-20616-31-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 30/48] builtin/apply: move 'limit_by_name' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:58Z","receivedAt":"2016-03-09T17:48:58Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 23 ++++++++++++++---------\n 1 file changed, 14 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex e94594d..186e451 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -71,6 +71,8 @@ struct apply_state {\n \tstruct lock_file lock_file;\n \n \tconst char *patch_input_file;\n+\n+\tstruct string_list limit_by_name;\n };\n \n static int p_value = 1;\n@@ -1979,13 +1981,14 @@ static void prefix_patch(struct apply_state *state, struct patch *p)\n  * include/exclude\n  */\n \n-static struct string_list limit_by_name;\n static int has_include;\n-static void add_name_limit(const char *name, int exclude)\n+static void add_name_limit(struct apply_state *state,\n+\t\t\t   const char *name,\n+\t\t\t   int exclude)\n {\n \tstruct string_list_item *it;\n \n-\tit = string_list_append(&limit_by_name, name);\n+\tit = string_list_append(&state->limit_by_name, name);\n \tit->util = exclude ? NULL : (void *) 1;\n }\n \n@@ -2003,8 +2006,8 @@ static int use_patch(struct apply_state *state, struct patch *p)\n \t}\n \n \t/* See if it matches any of exclude/include rule */\n-\tfor (i = 0; i < limit_by_name.nr; i++) {\n-\t\tstruct string_list_item *it = &limit_by_name.items[i];\n+\tfor (i = 0; i < state->limit_by_name.nr; i++) {\n+\t\tstruct string_list_item *it = &state->limit_by_name.items[i];\n \t\tif (!wildmatch(it->string, pathname, 0, NULL))\n \t\t\treturn (it->util != NULL);\n \t}\n@@ -4534,14 +4537,16 @@ static void git_apply_config(void)\n static int option_parse_exclude(const struct option *opt,\n \t\t\t\tconst char *arg, int unset)\n {\n-\tadd_name_limit(arg, 1);\n+\tstruct apply_state *state = opt->value;\n+\tadd_name_limit(state, arg, 1);\n \treturn 0;\n }\n \n static int option_parse_include(const struct option *opt,\n \t\t\t\tconst char *arg, int unset)\n {\n-\tadd_name_limit(arg, 0);\n+\tstruct apply_state *state = opt->value;\n+\tadd_name_limit(state, arg, 0);\n \thas_include = 1;\n \treturn 0;\n }\n@@ -4596,10 +4601,10 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tconst char *whitespace_option = NULL;\n \n \tstruct option builtin_apply_options[] = {\n-\t\t{ OPTION_CALLBACK, 0, \"exclude\", NULL, N_(\"path\"),\n+\t\t{ OPTION_CALLBACK, 0, \"exclude\", &state, N_(\"path\"),\n \t\t\tN_(\"don't apply changes matching the given path\"),\n \t\t\t0, option_parse_exclude },\n-\t\t{ OPTION_CALLBACK, 0, \"include\", NULL, N_(\"path\"),\n+\t\t{ OPTION_CALLBACK, 0, \"include\", &state, N_(\"path\"),\n \t\t\tN_(\"apply changes matching the given path\"),\n \t\t\t0, option_parse_include },\n \t\t{ OPTION_CALLBACK, 'p', NULL, NULL, N_(\"num\"),\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280453","messageId":"1457545756-20616-32-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 31/48] builtin/apply: move 'has_include' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:48:59Z","receivedAt":"2016-03-09T17:48:59Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 186e451..fa2940d 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -73,6 +73,7 @@ struct apply_state {\n \tconst char *patch_input_file;\n \n \tstruct string_list limit_by_name;\n+\tint has_include;\n };\n \n static int p_value = 1;\n@@ -1981,7 +1982,6 @@ static void prefix_patch(struct apply_state *state, struct patch *p)\n  * include/exclude\n  */\n \n-static int has_include;\n static void add_name_limit(struct apply_state *state,\n \t\t\t   const char *name,\n \t\t\t   int exclude)\n@@ -2017,7 +2017,7 @@ static int use_patch(struct apply_state *state, struct patch *p)\n \t * not used.  Otherwise, we saw bunch of exclude rules (or none)\n \t * and such a path is used.\n \t */\n-\treturn !has_include;\n+\treturn !state->has_include;\n }\n \n \n@@ -4547,7 +4547,7 @@ static int option_parse_include(const struct option *opt,\n {\n \tstruct apply_state *state = opt->value;\n \tadd_name_limit(state, arg, 0);\n-\thas_include = 1;\n+\tstate->has_include = 1;\n \treturn 0;\n }\n \n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280454","messageId":"1457545756-20616-33-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 32/48] builtin/apply: move 'p_value' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:00Z","receivedAt":"2016-03-09T17:49:00Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 151 +++++++++++++++++++++++++++++++++++++-------------------\n 1 file changed, 99 insertions(+), 52 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex fa2940d..8d4a900 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -66,6 +66,7 @@ struct apply_state {\n \n \tint line_termination;\n \n+\tint p_value;\n \tunsigned int p_context;\n \n \tstruct lock_file lock_file;\n@@ -76,7 +77,6 @@ struct apply_state {\n \tint has_include;\n };\n \n-static int p_value = 1;\n static int p_value_known;\n \n static const char * const apply_usage[] = {\n@@ -897,24 +897,24 @@ static void parse_traditional_patch(struct apply_state *state,\n \t\tq = guess_p_value(state, second);\n \t\tif (p < 0) p = q;\n \t\tif (0 <= p && p == q) {\n-\t\t\tp_value = p;\n+\t\t\tstate->p_value = p;\n \t\t\tp_value_known = 1;\n \t\t}\n \t}\n \tif (is_dev_null(first)) {\n \t\tpatch->is_new = 1;\n \t\tpatch->is_delete = 0;\n-\t\tname = find_name_traditional(second, NULL, p_value);\n+\t\tname = find_name_traditional(second, NULL, state->p_value);\n \t\tpatch->new_name = name;\n \t} else if (is_dev_null(second)) {\n \t\tpatch->is_new = 0;\n \t\tpatch->is_delete = 1;\n-\t\tname = find_name_traditional(first, NULL, p_value);\n+\t\tname = find_name_traditional(first, NULL, state->p_value);\n \t\tpatch->old_name = name;\n \t} else {\n \t\tchar *first_name;\n-\t\tfirst_name = find_name_traditional(first, NULL, p_value);\n-\t\tname = find_name_traditional(second, first_name, p_value);\n+\t\tfirst_name = find_name_traditional(first, NULL, state->p_value);\n+\t\tname = find_name_traditional(second, first_name, state->p_value);\n \t\tfree(first_name);\n \t\tif (has_epoch_timestamp(first)) {\n \t\t\tpatch->is_new = 1;\n@@ -933,7 +933,9 @@ static void parse_traditional_patch(struct apply_state *state,\n \t\tdie(_(\"unable to find filename in patch at line %d\"), linenr);\n }\n \n-static int gitdiff_hdrend(const char *line, struct patch *patch)\n+static int gitdiff_hdrend(struct apply_state *state,\n+\t\t\t  const char *line,\n+\t\t\t  struct patch *patch)\n {\n \treturn -1;\n }\n@@ -950,10 +952,14 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)\n #define DIFF_OLD_NAME 0\n #define DIFF_NEW_NAME 1\n \n-static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, int side)\n+static char *gitdiff_verify_name(struct apply_state *state,\n+\t\t\t\t const char *line,\n+\t\t\t\t int isnull,\n+\t\t\t\t char *orig_name,\n+\t\t\t\t int side)\n {\n \tif (!orig_name && !isnull)\n-\t\treturn find_name(line, NULL, p_value, TERM_TAB);\n+\t\treturn find_name(line, NULL, state->p_value, TERM_TAB);\n \n \tif (orig_name) {\n \t\tint len;\n@@ -963,7 +969,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n \t\tlen = strlen(name);\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, linenr);\n-\t\tanother = find_name(line, NULL, p_value, TERM_TAB);\n+\t\tanother = find_name(line, NULL, state->p_value, TERM_TAB);\n \t\tif (!another || memcmp(another, name, len + 1))\n \t\t\tdie((side == DIFF_NEW_NAME) ?\n \t\t\t    _(\"git apply: bad git-diff - inconsistent new filename on line %d\") :\n@@ -979,87 +985,111 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,\n \t}\n }\n \n-static int gitdiff_oldname(const char *line, struct patch *patch)\n+static int gitdiff_oldname(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   struct patch *patch)\n {\n \tchar *orig = patch->old_name;\n-\tpatch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name,\n+\tpatch->old_name = gitdiff_verify_name(state, line,\n+\t\t\t\t\t      patch->is_new, patch->old_name,\n \t\t\t\t\t      DIFF_OLD_NAME);\n \tif (orig != patch->old_name)\n \t\tfree(orig);\n \treturn 0;\n }\n \n-static int gitdiff_newname(const char *line, struct patch *patch)\n+static int gitdiff_newname(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   struct patch *patch)\n {\n \tchar *orig = patch->new_name;\n-\tpatch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name,\n+\tpatch->new_name = gitdiff_verify_name(state, line,\n+\t\t\t\t\t      patch->is_delete, patch->new_name,\n \t\t\t\t\t      DIFF_NEW_NAME);\n \tif (orig != patch->new_name)\n \t\tfree(orig);\n \treturn 0;\n }\n \n-static int gitdiff_oldmode(const char *line, struct patch *patch)\n+static int gitdiff_oldmode(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   struct patch *patch)\n {\n \tpatch->old_mode = strtoul(line, NULL, 8);\n \treturn 0;\n }\n \n-static int gitdiff_newmode(const char *line, struct patch *patch)\n+static int gitdiff_newmode(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   struct patch *patch)\n {\n \tpatch->new_mode = strtoul(line, NULL, 8);\n \treturn 0;\n }\n \n-static int gitdiff_delete(const char *line, struct patch *patch)\n+static int gitdiff_delete(struct apply_state *state,\n+\t\t\t  const char *line,\n+\t\t\t  struct patch *patch)\n {\n \tpatch->is_delete = 1;\n \tfree(patch->old_name);\n \tpatch->old_name = xstrdup_or_null(patch->def_name);\n-\treturn gitdiff_oldmode(line, patch);\n+\treturn gitdiff_oldmode(state, line, patch);\n }\n \n-static int gitdiff_newfile(const char *line, struct patch *patch)\n+static int gitdiff_newfile(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   struct patch *patch)\n {\n \tpatch->is_new = 1;\n \tfree(patch->new_name);\n \tpatch->new_name = xstrdup_or_null(patch->def_name);\n-\treturn gitdiff_newmode(line, patch);\n+\treturn gitdiff_newmode(state, line, patch);\n }\n \n-static int gitdiff_copysrc(const char *line, struct patch *patch)\n+static int gitdiff_copysrc(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   struct patch *patch)\n {\n \tpatch->is_copy = 1;\n \tfree(patch->old_name);\n-\tpatch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);\n+\tpatch->old_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n-static int gitdiff_copydst(const char *line, struct patch *patch)\n+static int gitdiff_copydst(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   struct patch *patch)\n {\n \tpatch->is_copy = 1;\n \tfree(patch->new_name);\n-\tpatch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);\n+\tpatch->new_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n-static int gitdiff_renamesrc(const char *line, struct patch *patch)\n+static int gitdiff_renamesrc(struct apply_state *state,\n+\t\t\t     const char *line,\n+\t\t\t     struct patch *patch)\n {\n \tpatch->is_rename = 1;\n \tfree(patch->old_name);\n-\tpatch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);\n+\tpatch->old_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n-static int gitdiff_renamedst(const char *line, struct patch *patch)\n+static int gitdiff_renamedst(struct apply_state *state,\n+\t\t\t     const char *line,\n+\t\t\t     struct patch *patch)\n {\n \tpatch->is_rename = 1;\n \tfree(patch->new_name);\n-\tpatch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);\n+\tpatch->new_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n-static int gitdiff_similarity(const char *line, struct patch *patch)\n+static int gitdiff_similarity(struct apply_state *state,\n+\t\t\t      const char *line,\n+\t\t\t      struct patch *patch)\n {\n \tunsigned long val = strtoul(line, NULL, 10);\n \tif (val <= 100)\n@@ -1067,7 +1097,9 @@ static int gitdiff_similarity(const char *line, struct patch *patch)\n \treturn 0;\n }\n \n-static int gitdiff_dissimilarity(const char *line, struct patch *patch)\n+static int gitdiff_dissimilarity(struct apply_state *state,\n+\t\t\t\t const char *line,\n+\t\t\t\t struct patch *patch)\n {\n \tunsigned long val = strtoul(line, NULL, 10);\n \tif (val <= 100)\n@@ -1075,7 +1107,9 @@ static int gitdiff_dissimilarity(const char *line, struct patch *patch)\n \treturn 0;\n }\n \n-static int gitdiff_index(const char *line, struct patch *patch)\n+static int gitdiff_index(struct apply_state *state,\n+\t\t\t const char *line,\n+\t\t\t struct patch *patch)\n {\n \t/*\n \t * index line is N hexadecimal, \"..\", N hexadecimal,\n@@ -1112,7 +1146,9 @@ static int gitdiff_index(const char *line, struct patch *patch)\n  * This is normal for a diff that doesn't change anything: we'll fall through\n  * into the next diff. Tell the parser to break out.\n  */\n-static int gitdiff_unrecognized(const char *line, struct patch *patch)\n+static int gitdiff_unrecognized(struct apply_state *state,\n+\t\t\t\tconst char *line,\n+\t\t\t\tstruct patch *patch)\n {\n \treturn -1;\n }\n@@ -1121,15 +1157,17 @@ static int gitdiff_unrecognized(const char *line, struct patch *patch)\n  * Skip p_value leading components from \"line\"; as we do not accept\n  * absolute paths, return NULL in that case.\n  */\n-static const char *skip_tree_prefix(const char *line, int llen)\n+static const char *skip_tree_prefix(struct apply_state *state,\n+\t\t\t\t    const char *line,\n+\t\t\t\t    int llen)\n {\n \tint nslash;\n \tint i;\n \n-\tif (!p_value)\n+\tif (!state->p_value)\n \t\treturn (llen && line[0] == '/') ? NULL : line;\n \n-\tnslash = p_value;\n+\tnslash = state->p_value;\n \tfor (i = 0; i < llen; i++) {\n \t\tint ch = line[i];\n \t\tif (ch == '/' && --nslash <= 0)\n@@ -1146,7 +1184,9 @@ static const char *skip_tree_prefix(const char *line, int llen)\n  * creation or deletion of an empty file.  In any of these cases,\n  * both sides are the same name under a/ and b/ respectively.\n  */\n-static char *git_header_name(const char *line, int llen)\n+static char *git_header_name(struct apply_state *state,\n+\t\t\t     const char *line,\n+\t\t\t     int llen)\n {\n \tconst char *name;\n \tconst char *second = NULL;\n@@ -1164,7 +1204,7 @@ static char *git_header_name(const char *line, int llen)\n \t\t\tgoto free_and_fail1;\n \n \t\t/* strip the a/b prefix including trailing slash */\n-\t\tcp = skip_tree_prefix(first.buf, first.len);\n+\t\tcp = skip_tree_prefix(state, first.buf, first.len);\n \t\tif (!cp)\n \t\t\tgoto free_and_fail1;\n \t\tstrbuf_remove(&first, 0, cp - first.buf);\n@@ -1181,7 +1221,7 @@ static char *git_header_name(const char *line, int llen)\n \t\tif (*second == '\"') {\n \t\t\tif (unquote_c_style(&sp, second, NULL))\n \t\t\t\tgoto free_and_fail1;\n-\t\t\tcp = skip_tree_prefix(sp.buf, sp.len);\n+\t\t\tcp = skip_tree_prefix(state, sp.buf, sp.len);\n \t\t\tif (!cp)\n \t\t\t\tgoto free_and_fail1;\n \t\t\t/* They must match, otherwise ignore */\n@@ -1192,7 +1232,7 @@ static char *git_header_name(const char *line, int llen)\n \t\t}\n \n \t\t/* unquoted second */\n-\t\tcp = skip_tree_prefix(second, line + llen - second);\n+\t\tcp = skip_tree_prefix(state, second, line + llen - second);\n \t\tif (!cp)\n \t\t\tgoto free_and_fail1;\n \t\tif (line + llen - cp != first.len ||\n@@ -1207,7 +1247,7 @@ static char *git_header_name(const char *line, int llen)\n \t}\n \n \t/* unquoted first name */\n-\tname = skip_tree_prefix(line, llen);\n+\tname = skip_tree_prefix(state, line, llen);\n \tif (!name)\n \t\treturn NULL;\n \n@@ -1223,7 +1263,7 @@ static char *git_header_name(const char *line, int llen)\n \t\t\tif (unquote_c_style(&sp, second, NULL))\n \t\t\t\tgoto free_and_fail2;\n \n-\t\t\tnp = skip_tree_prefix(sp.buf, sp.len);\n+\t\t\tnp = skip_tree_prefix(state, sp.buf, sp.len);\n \t\t\tif (!np)\n \t\t\t\tgoto free_and_fail2;\n \n@@ -1267,7 +1307,7 @@ static char *git_header_name(const char *line, int llen)\n \t\t\t */\n \t\t\tif (!name[len + 1])\n \t\t\t\treturn NULL; /* no postimage name */\n-\t\t\tsecond = skip_tree_prefix(name + len + 1,\n+\t\t\tsecond = skip_tree_prefix(state, name + len + 1,\n \t\t\t\t\t\t  line_len - (len + 1));\n \t\t\tif (!second)\n \t\t\t\treturn NULL;\n@@ -1283,7 +1323,11 @@ static char *git_header_name(const char *line, int llen)\n }\n \n /* Verify that we recognize the lines following a git header */\n-static int parse_git_header(const char *line, int len, unsigned int size, struct patch *patch)\n+static int parse_git_header(struct apply_state *state,\n+\t\t\t    const char *line,\n+\t\t\t    int len,\n+\t\t\t    unsigned int size,\n+\t\t\t    struct patch *patch)\n {\n \tunsigned long offset;\n \n@@ -1297,7 +1341,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct\n \t * or removing or adding empty files), so we get\n \t * the default name from the header.\n \t */\n-\tpatch->def_name = git_header_name(line, len);\n+\tpatch->def_name = git_header_name(state, line, len);\n \tif (patch->def_name && root.len) {\n \t\tchar *s = xstrfmt(\"%s%s\", root.buf, patch->def_name);\n \t\tfree(patch->def_name);\n@@ -1310,7 +1354,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct\n \tfor (offset = len ; size > 0 ; offset += len, size -= len, line += len, linenr++) {\n \t\tstatic const struct opentry {\n \t\t\tconst char *str;\n-\t\t\tint (*fn)(const char *, struct patch *);\n+\t\t\tint (*fn)(struct apply_state *, const char *, struct patch *);\n \t\t} optable[] = {\n \t\t\t{ \"@@ -\", gitdiff_hdrend },\n \t\t\t{ \"--- \", gitdiff_oldname },\n@@ -1340,7 +1384,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct\n \t\t\tint oplen = strlen(p->str);\n \t\t\tif (len < oplen || memcmp(p->str, line, oplen))\n \t\t\t\tcontinue;\n-\t\t\tif (p->fn(line + oplen, patch) < 0)\n+\t\t\tif (p->fn(state, line + oplen, patch) < 0)\n \t\t\t\treturn offset;\n \t\t\tbreak;\n \t\t}\n@@ -1510,7 +1554,7 @@ static int find_header(struct apply_state *state,\n \t\t * or mode change, so we handle that specially\n \t\t */\n \t\tif (!memcmp(\"diff --git \", line, 11)) {\n-\t\t\tint git_hdr_len = parse_git_header(line, len, size, patch);\n+\t\t\tint git_hdr_len = parse_git_header(state, line, len, size, patch);\n \t\t\tif (git_hdr_len <= len)\n \t\t\t\tcontinue;\n \t\t\tif (!patch->old_name && !patch->new_name) {\n@@ -1519,8 +1563,8 @@ static int find_header(struct apply_state *state,\n \t\t\t\t\t       \"%d leading pathname component (line %d)\",\n \t\t\t\t\t       \"git diff header lacks filename information when removing \"\n \t\t\t\t\t       \"%d leading pathname components (line %d)\",\n-\t\t\t\t\t       p_value),\n-\t\t\t\t\t    p_value, linenr);\n+\t\t\t\t\t       state->p_value),\n+\t\t\t\t\t    state->p_value, linenr);\n \t\t\t\tpatch->old_name = xstrdup(patch->def_name);\n \t\t\t\tpatch->new_name = xstrdup(patch->def_name);\n \t\t\t}\n@@ -4552,9 +4596,11 @@ static int option_parse_include(const struct option *opt,\n }\n \n static int option_parse_p(const struct option *opt,\n-\t\t\t  const char *arg, int unset)\n+\t\t\t  const char *arg,\n+\t\t\t  int unset)\n {\n-\tp_value = atoi(arg);\n+\tstruct apply_state *state = opt->value;\n+\tstate->p_value = atoi(arg);\n \tp_value_known = 1;\n \treturn 0;\n }\n@@ -4607,7 +4653,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t{ OPTION_CALLBACK, 0, \"include\", &state, N_(\"path\"),\n \t\t\tN_(\"apply changes matching the given path\"),\n \t\t\t0, option_parse_include },\n-\t\t{ OPTION_CALLBACK, 'p', NULL, NULL, N_(\"num\"),\n+\t\t{ OPTION_CALLBACK, 'p', NULL, &state, N_(\"num\"),\n \t\t\tN_(\"remove <num> leading slashes from traditional diff paths\"),\n \t\t\t0, option_parse_p },\n \t\tOPT_BOOL(0, \"no-add\", &state.no_add,\n@@ -4675,6 +4721,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.apply = 1;\n \tstate.newfd = -1;\n \tstate.line_termination = '\\n';\n+\tstate.p_value = 1;\n \tstate.p_context = UINT_MAX;\n \n \tgit_apply_config();\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280456","messageId":"1457545756-20616-34-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 33/48] builtin/apply: move 'p_value_known' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:01Z","receivedAt":"2016-03-09T17:49:01Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 9 ++++-----\n 1 file changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 8d4a900..cb995c8 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -67,6 +67,7 @@ struct apply_state {\n \tint line_termination;\n \n \tint p_value;\n+\tint p_value_known;\n \tunsigned int p_context;\n \n \tstruct lock_file lock_file;\n@@ -77,8 +78,6 @@ struct apply_state {\n \tint has_include;\n };\n \n-static int p_value_known;\n-\n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n \tNULL\n@@ -891,14 +890,14 @@ static void parse_traditional_patch(struct apply_state *state,\n \n \tfirst += 4;\t/* skip \"--- \" */\n \tsecond += 4;\t/* skip \"+++ \" */\n-\tif (!p_value_known) {\n+\tif (!state->p_value_known) {\n \t\tint p, q;\n \t\tp = guess_p_value(state, first);\n \t\tq = guess_p_value(state, second);\n \t\tif (p < 0) p = q;\n \t\tif (0 <= p && p == q) {\n \t\t\tstate->p_value = p;\n-\t\t\tp_value_known = 1;\n+\t\t\tstate->p_value_known = 1;\n \t\t}\n \t}\n \tif (is_dev_null(first)) {\n@@ -4601,7 +4600,7 @@ static int option_parse_p(const struct option *opt,\n {\n \tstruct apply_state *state = opt->value;\n \tstate->p_value = atoi(arg);\n-\tp_value_known = 1;\n+\tstate->p_value_known = 1;\n \treturn 0;\n }\n \n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280455","messageId":"1457545756-20616-35-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 34/48] builtin/apply: move 'root' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:02Z","receivedAt":"2016-03-09T17:49:02Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 82 ++++++++++++++++++++++++++++++++++-----------------------\n 1 file changed, 49 insertions(+), 33 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex cb995c8..8571646 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -76,6 +76,8 @@ struct apply_state {\n \n \tstruct string_list limit_by_name;\n \tint has_include;\n+\n+\tstruct strbuf root;\n };\n \n static const char * const apply_usage[] = {\n@@ -99,8 +101,6 @@ static enum ws_ignore {\n } ws_ignore_action = ignore_ws_none;\n \n \n-static struct strbuf root = STRBUF_INIT;\n-\n static void parse_whitespace_option(const char *option)\n {\n \tif (!option) {\n@@ -490,7 +490,10 @@ static char *squash_slash(char *name)\n \treturn name;\n }\n \n-static char *find_name_gnu(const char *line, const char *def, int p_v)\n+static char *find_name_gnu(struct apply_state *state,\n+\t\t\t   const char *line,\n+\t\t\t   const char *def,\n+\t\t\t   int p_v)\n {\n \tstruct strbuf name = STRBUF_INIT;\n \tchar *cp;\n@@ -514,8 +517,8 @@ static char *find_name_gnu(const char *line, const char *def, int p_v)\n \t}\n \n \tstrbuf_remove(&name, 0, cp - name.buf);\n-\tif (root.len)\n-\t\tstrbuf_insert(&name, 0, root.buf, root.len);\n+\tif (state->root.len)\n+\t\tstrbuf_insert(&name, 0, state->root.buf, state->root.len);\n \treturn squash_slash(strbuf_detach(&name, NULL));\n }\n \n@@ -678,8 +681,12 @@ static size_t diff_timestamp_len(const char *line, size_t len)\n \treturn line + len - end;\n }\n \n-static char *find_name_common(const char *line, const char *def,\n-\t\t\t      int p_v, const char *end, int terminate)\n+static char *find_name_common(struct apply_state *state,\n+\t\t\t      const char *line,\n+\t\t\t      const char *def,\n+\t\t\t      int p_v,\n+\t\t\t      const char *end,\n+\t\t\t      int terminate)\n {\n \tint len;\n \tconst char *start = NULL;\n@@ -717,32 +724,39 @@ static char *find_name_common(const char *line, const char *def,\n \t\t\treturn squash_slash(xstrdup(def));\n \t}\n \n-\tif (root.len) {\n-\t\tchar *ret = xstrfmt(\"%s%.*s\", root.buf, len, start);\n+\tif (state->root.len) {\n+\t\tchar *ret = xstrfmt(\"%s%.*s\", state->root.buf, len, start);\n \t\treturn squash_slash(ret);\n \t}\n \n \treturn squash_slash(xmemdupz(start, len));\n }\n \n-static char *find_name(const char *line, char *def, int p_v, int terminate)\n+static char *find_name(struct apply_state *state,\n+\t\t       const char *line,\n+\t\t       char *def,\n+\t\t       int p_v,\n+\t\t       int terminate)\n {\n \tif (*line == '\"') {\n-\t\tchar *name = find_name_gnu(line, def, p_v);\n+\t\tchar *name = find_name_gnu(state, line, def, p_v);\n \t\tif (name)\n \t\t\treturn name;\n \t}\n \n-\treturn find_name_common(line, def, p_v, NULL, terminate);\n+\treturn find_name_common(state, line, def, p_v, NULL, terminate);\n }\n \n-static char *find_name_traditional(const char *line, char *def, int p_v)\n+static char *find_name_traditional(struct apply_state *state,\n+\t\t\t\t   const char *line,\n+\t\t\t\t   char *def,\n+\t\t\t\t   int p_v)\n {\n \tsize_t len;\n \tsize_t date_len;\n \n \tif (*line == '\"') {\n-\t\tchar *name = find_name_gnu(line, def, p_v);\n+\t\tchar *name = find_name_gnu(state, line, def, p_v);\n \t\tif (name)\n \t\t\treturn name;\n \t}\n@@ -750,10 +764,10 @@ static char *find_name_traditional(const char *line, char *def, int p_v)\n \tlen = strchrnul(line, '\\n') - line;\n \tdate_len = diff_timestamp_len(line, len);\n \tif (!date_len)\n-\t\treturn find_name_common(line, def, p_v, NULL, TERM_TAB);\n+\t\treturn find_name_common(state, line, def, p_v, NULL, TERM_TAB);\n \tlen -= date_len;\n \n-\treturn find_name_common(line, def, p_v, line + len, 0);\n+\treturn find_name_common(state, line, def, p_v, line + len, 0);\n }\n \n static int count_slashes(const char *cp)\n@@ -778,7 +792,7 @@ static int guess_p_value(struct apply_state *state, const char *nameline)\n \n \tif (is_dev_null(nameline))\n \t\treturn -1;\n-\tname = find_name_traditional(nameline, NULL, 0);\n+\tname = find_name_traditional(state, nameline, NULL, 0);\n \tif (!name)\n \t\treturn -1;\n \tcp = strchr(name, '/');\n@@ -903,17 +917,17 @@ static void parse_traditional_patch(struct apply_state *state,\n \tif (is_dev_null(first)) {\n \t\tpatch->is_new = 1;\n \t\tpatch->is_delete = 0;\n-\t\tname = find_name_traditional(second, NULL, state->p_value);\n+\t\tname = find_name_traditional(state, second, NULL, state->p_value);\n \t\tpatch->new_name = name;\n \t} else if (is_dev_null(second)) {\n \t\tpatch->is_new = 0;\n \t\tpatch->is_delete = 1;\n-\t\tname = find_name_traditional(first, NULL, state->p_value);\n+\t\tname = find_name_traditional(state, first, NULL, state->p_value);\n \t\tpatch->old_name = name;\n \t} else {\n \t\tchar *first_name;\n-\t\tfirst_name = find_name_traditional(first, NULL, state->p_value);\n-\t\tname = find_name_traditional(second, first_name, state->p_value);\n+\t\tfirst_name = find_name_traditional(state, first, NULL, state->p_value);\n+\t\tname = find_name_traditional(state, second, first_name, state->p_value);\n \t\tfree(first_name);\n \t\tif (has_epoch_timestamp(first)) {\n \t\t\tpatch->is_new = 1;\n@@ -958,7 +972,7 @@ static char *gitdiff_verify_name(struct apply_state *state,\n \t\t\t\t int side)\n {\n \tif (!orig_name && !isnull)\n-\t\treturn find_name(line, NULL, state->p_value, TERM_TAB);\n+\t\treturn find_name(state, line, NULL, state->p_value, TERM_TAB);\n \n \tif (orig_name) {\n \t\tint len;\n@@ -968,7 +982,7 @@ static char *gitdiff_verify_name(struct apply_state *state,\n \t\tlen = strlen(name);\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, linenr);\n-\t\tanother = find_name(line, NULL, state->p_value, TERM_TAB);\n+\t\tanother = find_name(state, line, NULL, state->p_value, TERM_TAB);\n \t\tif (!another || memcmp(another, name, len + 1))\n \t\t\tdie((side == DIFF_NEW_NAME) ?\n \t\t\t    _(\"git apply: bad git-diff - inconsistent new filename on line %d\") :\n@@ -1052,7 +1066,7 @@ static int gitdiff_copysrc(struct apply_state *state,\n {\n \tpatch->is_copy = 1;\n \tfree(patch->old_name);\n-\tpatch->old_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n+\tpatch->old_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n@@ -1062,7 +1076,7 @@ static int gitdiff_copydst(struct apply_state *state,\n {\n \tpatch->is_copy = 1;\n \tfree(patch->new_name);\n-\tpatch->new_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n+\tpatch->new_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n@@ -1072,7 +1086,7 @@ static int gitdiff_renamesrc(struct apply_state *state,\n {\n \tpatch->is_rename = 1;\n \tfree(patch->old_name);\n-\tpatch->old_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n+\tpatch->old_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n@@ -1082,7 +1096,7 @@ static int gitdiff_renamedst(struct apply_state *state,\n {\n \tpatch->is_rename = 1;\n \tfree(patch->new_name);\n-\tpatch->new_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n+\tpatch->new_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);\n \treturn 0;\n }\n \n@@ -1341,8 +1355,8 @@ static int parse_git_header(struct apply_state *state,\n \t * the default name from the header.\n \t */\n \tpatch->def_name = git_header_name(state, line, len);\n-\tif (patch->def_name && root.len) {\n-\t\tchar *s = xstrfmt(\"%s%s\", root.buf, patch->def_name);\n+\tif (patch->def_name && state->root.len) {\n+\t\tchar *s = xstrfmt(\"%s%s\", state->root.buf, patch->def_name);\n \t\tfree(patch->def_name);\n \t\tpatch->def_name = s;\n \t}\n@@ -4627,9 +4641,10 @@ static int option_parse_whitespace(const struct option *opt,\n static int option_parse_directory(const struct option *opt,\n \t\t\t\t  const char *arg, int unset)\n {\n-\tstrbuf_reset(&root);\n-\tstrbuf_addstr(&root, arg);\n-\tstrbuf_complete(&root, '/');\n+\tstruct apply_state *state = opt->value;\n+\tstrbuf_reset(&state->root);\n+\tstrbuf_addstr(&state->root, arg);\n+\tstrbuf_complete(&state->root, '/');\n \treturn 0;\n }\n \n@@ -4708,7 +4723,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tOPT_BIT(0, \"recount\", &options,\n \t\t\tN_(\"do not trust the line counts in the hunk headers\"),\n \t\t\tRECOUNT),\n-\t\t{ OPTION_CALLBACK, 0, \"directory\", NULL, N_(\"root\"),\n+\t\t{ OPTION_CALLBACK, 0, \"directory\", &state, N_(\"root\"),\n \t\t\tN_(\"prepend <root> to all filenames\"),\n \t\t\t0, option_parse_directory },\n \t\tOPT_END()\n@@ -4722,6 +4737,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.line_termination = '\\n';\n \tstate.p_value = 1;\n \tstate.p_context = UINT_MAX;\n+\tstrbuf_init(&state.root, 0);\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280459","messageId":"1457545756-20616-36-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 35/48] builtin/apply: move 'whitespace_error' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:03Z","receivedAt":"2016-03-09T17:49:03Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 27 ++++++++++++++-------------\n 1 file changed, 14 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 8571646..1d665c2 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -78,6 +78,8 @@ struct apply_state {\n \tint has_include;\n \n \tstruct strbuf root;\n+\n+\tint whitespace_error;\n };\n \n static const char * const apply_usage[] = {\n@@ -91,7 +93,6 @@ static enum ws_error_action {\n \tdie_on_ws_error,\n \tcorrect_ws_error\n } ws_error_action = warn_on_ws_error;\n-static int whitespace_error;\n static int squelch_whitespace_errors = 5;\n static int applied_after_fixing_ws;\n \n@@ -1622,9 +1623,9 @@ static void record_ws_error(struct apply_state *state,\n \tif (!result)\n \t\treturn;\n \n-\twhitespace_error++;\n+\tstate->whitespace_error++;\n \tif (squelch_whitespace_errors &&\n-\t    squelch_whitespace_errors < whitespace_error)\n+\t    squelch_whitespace_errors < state->whitespace_error)\n \t\treturn;\n \n \terr = whitespace_error_string(result);\n@@ -2875,7 +2876,7 @@ static int apply_one_fragment(struct apply_state *state,\n \n \t\t\tstart = newlines.len;\n \t\t\tif (first != '+' ||\n-\t\t\t    !whitespace_error ||\n+\t\t\t    !state->whitespace_error ||\n \t\t\t    ws_error_action != correct_ws_error) {\n \t\t\t\tstrbuf_add(&newlines, patch + 1, plen);\n \t\t\t}\n@@ -4542,7 +4543,7 @@ static int apply_patch(struct apply_state *state,\n \tif (!list && !skipped_patch)\n \t\tdie(_(\"unrecognized input\"));\n \n-\tif (whitespace_error && (ws_error_action == die_on_ws_error))\n+\tif (state->whitespace_error && (ws_error_action == die_on_ws_error))\n \t\tstate->apply = 0;\n \n \tstate->update_index = state->check_index && state->apply;\n@@ -4795,11 +4796,11 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tset_default_whitespace_mode(&state, whitespace_option);\n \tif (read_stdin)\n \t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n-\tif (whitespace_error) {\n+\tif (state.whitespace_error) {\n \t\tif (squelch_whitespace_errors &&\n-\t\t    squelch_whitespace_errors < whitespace_error) {\n+\t\t    squelch_whitespace_errors < state.whitespace_error) {\n \t\t\tint squelched =\n-\t\t\t\twhitespace_error - squelch_whitespace_errors;\n+\t\t\t\tstate.whitespace_error - squelch_whitespace_errors;\n \t\t\twarning(Q_(\"squelched %d whitespace error\",\n \t\t\t\t   \"squelched %d whitespace errors\",\n \t\t\t\t   squelched),\n@@ -4808,18 +4809,18 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tif (ws_error_action == die_on_ws_error)\n \t\t\tdie(Q_(\"%d line adds whitespace errors.\",\n \t\t\t       \"%d lines add whitespace errors.\",\n-\t\t\t       whitespace_error),\n-\t\t\t    whitespace_error);\n+\t\t\t       state.whitespace_error),\n+\t\t\t    state.whitespace_error);\n \t\tif (applied_after_fixing_ws && state.apply)\n \t\t\twarning(\"%d line%s applied after\"\n \t\t\t\t\" fixing whitespace errors.\",\n \t\t\t\tapplied_after_fixing_ws,\n \t\t\t\tapplied_after_fixing_ws == 1 ? \"\" : \"s\");\n-\t\telse if (whitespace_error)\n+\t\telse if (state.whitespace_error)\n \t\t\twarning(Q_(\"%d line adds whitespace errors.\",\n \t\t\t\t   \"%d lines add whitespace errors.\",\n-\t\t\t\t   whitespace_error),\n-\t\t\t\twhitespace_error);\n+\t\t\t\t   state.whitespace_error),\n+\t\t\t\tstate.whitespace_error);\n \t}\n \n \tif (state.update_index) {\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280461","messageId":"1457545756-20616-37-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 36/48] builtin/apply: move 'whitespace_option' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:04Z","receivedAt":"2016-03-09T17:49:04Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This will enable further refactoring.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 13 ++++++-------\n 1 file changed, 6 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 1d665c2..63eb031 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -79,6 +79,7 @@ struct apply_state {\n \n \tstruct strbuf root;\n \n+\tconst char *whitespace_option;\n \tint whitespace_error;\n };\n \n@@ -4632,9 +4633,9 @@ static int option_parse_space_change(const struct option *opt,\n static int option_parse_whitespace(const struct option *opt,\n \t\t\t\t   const char *arg, int unset)\n {\n-\tconst char **whitespace_option = opt->value;\n+\tstruct apply_state *state = opt->value;\n \n-\t*whitespace_option = arg;\n+\tstate->whitespace_option = arg;\n \tparse_whitespace_option(arg);\n \treturn 0;\n }\n@@ -4659,8 +4660,6 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tint read_stdin = 1;\n \tstruct apply_state state;\n \n-\tconst char *whitespace_option = NULL;\n-\n \tstruct option builtin_apply_options[] = {\n \t\t{ OPTION_CALLBACK, 0, \"exclude\", &state, N_(\"path\"),\n \t\t\tN_(\"don't apply changes matching the given path\"),\n@@ -4700,7 +4699,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\tN_(\"paths are separated with NUL character\"), '\\0'),\n \t\tOPT_INTEGER('C', NULL, &state.p_context,\n \t\t\t\tN_(\"ensure at least <n> lines of context match\")),\n-\t\t{ OPTION_CALLBACK, 0, \"whitespace\", &whitespace_option, N_(\"action\"),\n+\t\t{ OPTION_CALLBACK, 0, \"whitespace\", &state, N_(\"action\"),\n \t\t\tN_(\"detect new or modified lines that have whitespace errors\"),\n \t\t\t0, option_parse_whitespace },\n \t\t{ OPTION_CALLBACK, 0, \"ignore-space-change\", NULL, NULL,\n@@ -4789,11 +4788,11 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tif (fd < 0)\n \t\t\tdie_errno(_(\"can't open patch '%s'\"), arg);\n \t\tread_stdin = 0;\n-\t\tset_default_whitespace_mode(&state, whitespace_option);\n+\t\tset_default_whitespace_mode(&state, state.whitespace_option);\n \t\terrs |= apply_patch(&state, fd, arg, options);\n \t\tclose(fd);\n \t}\n-\tset_default_whitespace_mode(&state, whitespace_option);\n+\tset_default_whitespace_mode(&state, state.whitespace_option);\n \tif (read_stdin)\n \t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n \tif (state.whitespace_error) {\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280460","messageId":"1457545756-20616-38-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 37/48] builtin/apply: remove whitespace_option arg from set_default_whitespace_mode()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:05Z","receivedAt":"2016-03-09T17:49:05Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 9 ++++-----\n 1 file changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 63eb031..3c00551 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -148,10 +148,9 @@ static void parse_ignorewhitespace_option(const char *option)\n \tdie(_(\"unrecognized whitespace ignore option '%s'\"), option);\n }\n \n-static void set_default_whitespace_mode(struct apply_state *state,\n-\t\t\t\t\tconst char *whitespace_option)\n+static void set_default_whitespace_mode(struct apply_state *state)\n {\n-\tif (!whitespace_option && !apply_default_whitespace)\n+\tif (!state->whitespace_option && !apply_default_whitespace)\n \t\tws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);\n }\n \n@@ -4788,11 +4787,11 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tif (fd < 0)\n \t\t\tdie_errno(_(\"can't open patch '%s'\"), arg);\n \t\tread_stdin = 0;\n-\t\tset_default_whitespace_mode(&state, state.whitespace_option);\n+\t\tset_default_whitespace_mode(&state);\n \t\terrs |= apply_patch(&state, fd, arg, options);\n \t\tclose(fd);\n \t}\n-\tset_default_whitespace_mode(&state, state.whitespace_option);\n+\tset_default_whitespace_mode(&state);\n \tif (read_stdin)\n \t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n \tif (state.whitespace_error) {\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280457","messageId":"1457545756-20616-39-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 38/48] builtin/apply: move 'squelch_whitespace_errors' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:06Z","receivedAt":"2016-03-09T17:49:06Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 22 +++++++++++-----------\n 1 file changed, 11 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 3c00551..a2e1e51 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -81,6 +81,7 @@ struct apply_state {\n \n \tconst char *whitespace_option;\n \tint whitespace_error;\n+\tint squelch_whitespace_errors;\n };\n \n static const char * const apply_usage[] = {\n@@ -94,7 +95,6 @@ static enum ws_error_action {\n \tdie_on_ws_error,\n \tcorrect_ws_error\n } ws_error_action = warn_on_ws_error;\n-static int squelch_whitespace_errors = 5;\n static int applied_after_fixing_ws;\n \n static enum ws_ignore {\n@@ -103,7 +103,7 @@ static enum ws_ignore {\n } ws_ignore_action = ignore_ws_none;\n \n \n-static void parse_whitespace_option(const char *option)\n+static void parse_whitespace_option(struct apply_state *state, const char *option)\n {\n \tif (!option) {\n \t\tws_error_action = warn_on_ws_error;\n@@ -123,7 +123,7 @@ static void parse_whitespace_option(const char *option)\n \t}\n \tif (!strcmp(option, \"error-all\")) {\n \t\tws_error_action = die_on_ws_error;\n-\t\tsquelch_whitespace_errors = 0;\n+\t\tstate->squelch_whitespace_errors = 0;\n \t\treturn;\n \t}\n \tif (!strcmp(option, \"strip\") || !strcmp(option, \"fix\")) {\n@@ -1624,8 +1624,8 @@ static void record_ws_error(struct apply_state *state,\n \t\treturn;\n \n \tstate->whitespace_error++;\n-\tif (squelch_whitespace_errors &&\n-\t    squelch_whitespace_errors < state->whitespace_error)\n+\tif (state->squelch_whitespace_errors &&\n+\t    state->squelch_whitespace_errors < state->whitespace_error)\n \t\treturn;\n \n \terr = whitespace_error_string(result);\n@@ -4633,9 +4633,8 @@ static int option_parse_whitespace(const struct option *opt,\n \t\t\t\t   const char *arg, int unset)\n {\n \tstruct apply_state *state = opt->value;\n-\n \tstate->whitespace_option = arg;\n-\tparse_whitespace_option(arg);\n+\tparse_whitespace_option(state, arg);\n \treturn 0;\n }\n \n@@ -4736,11 +4735,12 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.line_termination = '\\n';\n \tstate.p_value = 1;\n \tstate.p_context = UINT_MAX;\n+\tstate.squelch_whitespace_errors = 5;\n \tstrbuf_init(&state.root, 0);\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n-\t\tparse_whitespace_option(apply_default_whitespace);\n+\t\tparse_whitespace_option(&state, apply_default_whitespace);\n \tif (apply_default_ignorewhitespace)\n \t\tparse_ignorewhitespace_option(apply_default_ignorewhitespace);\n \n@@ -4795,10 +4795,10 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tif (read_stdin)\n \t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n \tif (state.whitespace_error) {\n-\t\tif (squelch_whitespace_errors &&\n-\t\t    squelch_whitespace_errors < state.whitespace_error) {\n+\t\tif (state.squelch_whitespace_errors &&\n+\t\t    state.squelch_whitespace_errors < state.whitespace_error) {\n \t\t\tint squelched =\n-\t\t\t\tstate.whitespace_error - squelch_whitespace_errors;\n+\t\t\t\tstate.whitespace_error - state.squelch_whitespace_errors;\n \t\t\twarning(Q_(\"squelched %d whitespace error\",\n \t\t\t\t   \"squelched %d whitespace errors\",\n \t\t\t\t   squelched),\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280462","messageId":"1457545756-20616-40-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 39/48] builtin/apply: move 'applied_after_fixing_ws' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:07Z","receivedAt":"2016-03-09T17:49:07Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex a2e1e51..9a2b8af 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -82,6 +82,7 @@ struct apply_state {\n \tconst char *whitespace_option;\n \tint whitespace_error;\n \tint squelch_whitespace_errors;\n+\tint applied_after_fixing_ws;\n };\n \n static const char * const apply_usage[] = {\n@@ -95,7 +96,6 @@ static enum ws_error_action {\n \tdie_on_ws_error,\n \tcorrect_ws_error\n } ws_error_action = warn_on_ws_error;\n-static int applied_after_fixing_ws;\n \n static enum ws_ignore {\n \tignore_ws_none,\n@@ -2881,7 +2881,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\t\tstrbuf_add(&newlines, patch + 1, plen);\n \t\t\t}\n \t\t\telse {\n-\t\t\t\tws_fix_copy(&newlines, patch + 1, plen, ws_rule, &applied_after_fixing_ws);\n+\t\t\t\tws_fix_copy(&newlines, patch + 1, plen, ws_rule, &state->applied_after_fixing_ws);\n \t\t\t}\n \t\t\tadd_line_info(&postimage, newlines.buf + start, newlines.len - start,\n \t\t\t\t      (first == '+' ? 0 : LINE_COMMON));\n@@ -4809,11 +4809,11 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\t       \"%d lines add whitespace errors.\",\n \t\t\t       state.whitespace_error),\n \t\t\t    state.whitespace_error);\n-\t\tif (applied_after_fixing_ws && state.apply)\n+\t\tif (state.applied_after_fixing_ws && state.apply)\n \t\t\twarning(\"%d line%s applied after\"\n \t\t\t\t\" fixing whitespace errors.\",\n-\t\t\t\tapplied_after_fixing_ws,\n-\t\t\t\tapplied_after_fixing_ws == 1 ? \"\" : \"s\");\n+\t\t\t\tstate.applied_after_fixing_ws,\n+\t\t\t\tstate.applied_after_fixing_ws == 1 ? \"\" : \"s\");\n \t\telse if (state.whitespace_error)\n \t\t\twarning(Q_(\"%d line adds whitespace errors.\",\n \t\t\t\t   \"%d lines add whitespace errors.\",\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280465","messageId":"1457545756-20616-41-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 40/48] builtin/apply: move 'ws_error_action' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:08Z","receivedAt":"2016-03-09T17:49:08Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 62 +++++++++++++++++++++++++++++++--------------------------\n 1 file changed, 34 insertions(+), 28 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 9a2b8af..d427c3c 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -21,6 +21,13 @@\n #include \"ll-merge.h\"\n #include \"rerere.h\"\n \n+enum ws_error_action {\n+\tnowarn_ws_error,\n+\twarn_on_ws_error,\n+\tdie_on_ws_error,\n+\tcorrect_ws_error\n+};\n+\n struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n@@ -83,6 +90,8 @@ struct apply_state {\n \tint whitespace_error;\n \tint squelch_whitespace_errors;\n \tint applied_after_fixing_ws;\n+\n+\tenum ws_error_action ws_error_action;\n };\n \n static const char * const apply_usage[] = {\n@@ -90,12 +99,6 @@ static const char * const apply_usage[] = {\n \tNULL\n };\n \n-static enum ws_error_action {\n-\tnowarn_ws_error,\n-\twarn_on_ws_error,\n-\tdie_on_ws_error,\n-\tcorrect_ws_error\n-} ws_error_action = warn_on_ws_error;\n \n static enum ws_ignore {\n \tignore_ws_none,\n@@ -106,28 +109,28 @@ static enum ws_ignore {\n static void parse_whitespace_option(struct apply_state *state, const char *option)\n {\n \tif (!option) {\n-\t\tws_error_action = warn_on_ws_error;\n+\t\tstate->ws_error_action = warn_on_ws_error;\n \t\treturn;\n \t}\n \tif (!strcmp(option, \"warn\")) {\n-\t\tws_error_action = warn_on_ws_error;\n+\t\tstate->ws_error_action = warn_on_ws_error;\n \t\treturn;\n \t}\n \tif (!strcmp(option, \"nowarn\")) {\n-\t\tws_error_action = nowarn_ws_error;\n+\t\tstate->ws_error_action = nowarn_ws_error;\n \t\treturn;\n \t}\n \tif (!strcmp(option, \"error\")) {\n-\t\tws_error_action = die_on_ws_error;\n+\t\tstate->ws_error_action = die_on_ws_error;\n \t\treturn;\n \t}\n \tif (!strcmp(option, \"error-all\")) {\n-\t\tws_error_action = die_on_ws_error;\n+\t\tstate->ws_error_action = die_on_ws_error;\n \t\tstate->squelch_whitespace_errors = 0;\n \t\treturn;\n \t}\n \tif (!strcmp(option, \"strip\") || !strcmp(option, \"fix\")) {\n-\t\tws_error_action = correct_ws_error;\n+\t\tstate->ws_error_action = correct_ws_error;\n \t\treturn;\n \t}\n \tdie(_(\"unrecognized whitespace option '%s'\"), option);\n@@ -151,7 +154,7 @@ static void parse_ignorewhitespace_option(const char *option)\n static void set_default_whitespace_mode(struct apply_state *state)\n {\n \tif (!state->whitespace_option && !apply_default_whitespace)\n-\t\tws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);\n+\t\tstate->ws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);\n }\n \n /*\n@@ -1695,12 +1698,12 @@ static int parse_fragment(struct apply_state *state,\n \t\t\t\tleading++;\n \t\t\ttrailing++;\n \t\t\tif (!state->apply_in_reverse &&\n-\t\t\t    ws_error_action == correct_ws_error)\n+\t\t\t    state->ws_error_action == correct_ws_error)\n \t\t\t\tcheck_whitespace(state, line, len, patch->ws_rule);\n \t\t\tbreak;\n \t\tcase '-':\n \t\t\tif (state->apply_in_reverse &&\n-\t\t\t    ws_error_action != nowarn_ws_error)\n+\t\t\t    state->ws_error_action != nowarn_ws_error)\n \t\t\t\tcheck_whitespace(state, line, len, patch->ws_rule);\n \t\t\tdeleted++;\n \t\t\toldlines--;\n@@ -1708,7 +1711,7 @@ static int parse_fragment(struct apply_state *state,\n \t\t\tbreak;\n \t\tcase '+':\n \t\t\tif (!state->apply_in_reverse &&\n-\t\t\t    ws_error_action != nowarn_ws_error)\n+\t\t\t    state->ws_error_action != nowarn_ws_error)\n \t\t\t\tcheck_whitespace(state, line, len, patch->ws_rule);\n \t\t\tadded++;\n \t\t\tnewlines--;\n@@ -2414,7 +2417,8 @@ static int line_by_line_fuzzy_match(struct image *img,\n \treturn 1;\n }\n \n-static int match_fragment(struct image *img,\n+static int match_fragment(struct apply_state *state,\n+\t\t\t  struct image *img,\n \t\t\t  struct image *preimage,\n \t\t\t  struct image *postimage,\n \t\t\t  unsigned long try,\n@@ -2435,7 +2439,7 @@ static int match_fragment(struct image *img,\n \t\tpreimage_limit = preimage->nr;\n \t\tif (match_end && (preimage->nr + try_lno != img->nr))\n \t\t\treturn 0;\n-\t} else if (ws_error_action == correct_ws_error &&\n+\t} else if (state->ws_error_action == correct_ws_error &&\n \t\t   (ws_rule & WS_BLANK_AT_EOF)) {\n \t\t/*\n \t\t * This hunk extends beyond the end of img, and we are\n@@ -2508,7 +2512,7 @@ static int match_fragment(struct image *img,\n \t\treturn line_by_line_fuzzy_match(img, preimage, postimage, try, try_lno, preimage_limit);\n \t}\n \n-\tif (ws_error_action != correct_ws_error)\n+\tif (state->ws_error_action != correct_ws_error)\n \t\treturn 0;\n \n \t/*\n@@ -2620,7 +2624,8 @@ static int match_fragment(struct image *img,\n \treturn 0;\n }\n \n-static int find_pos(struct image *img,\n+static int find_pos(struct apply_state *state,\n+\t\t    struct image *img,\n \t\t    struct image *preimage,\n \t\t    struct image *postimage,\n \t\t    int line,\n@@ -2664,7 +2669,7 @@ static int find_pos(struct image *img,\n \ttry_lno = line;\n \n \tfor (i = 0; ; i++) {\n-\t\tif (match_fragment(img, preimage, postimage,\n+\t\tif (match_fragment(state, img, preimage, postimage,\n \t\t\t\t   try, try_lno, ws_rule,\n \t\t\t\t   match_beginning, match_end))\n \t\t\treturn try_lno;\n@@ -2877,7 +2882,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\tstart = newlines.len;\n \t\t\tif (first != '+' ||\n \t\t\t    !state->whitespace_error ||\n-\t\t\t    ws_error_action != correct_ws_error) {\n+\t\t\t    state->ws_error_action != correct_ws_error) {\n \t\t\t\tstrbuf_add(&newlines, patch + 1, plen);\n \t\t\t}\n \t\t\telse {\n@@ -2955,7 +2960,7 @@ static int apply_one_fragment(struct apply_state *state,\n \n \tfor (;;) {\n \n-\t\tapplied_pos = find_pos(img, &preimage, &postimage, pos,\n+\t\tapplied_pos = find_pos(state, img, &preimage, &postimage, pos,\n \t\t\t\t       ws_rule, match_beginning, match_end);\n \n \t\tif (applied_pos >= 0)\n@@ -2991,10 +2996,10 @@ static int apply_one_fragment(struct apply_state *state,\n \t\tif (new_blank_lines_at_end &&\n \t\t    preimage.nr + applied_pos >= img->nr &&\n \t\t    (ws_rule & WS_BLANK_AT_EOF) &&\n-\t\t    ws_error_action != nowarn_ws_error) {\n+\t\t    state->ws_error_action != nowarn_ws_error) {\n \t\t\trecord_ws_error(state, WS_BLANK_AT_EOF, \"+\", 1,\n \t\t\t\t\tfound_new_blank_lines_at_end);\n-\t\t\tif (ws_error_action == correct_ws_error) {\n+\t\t\tif (state->ws_error_action == correct_ws_error) {\n \t\t\t\twhile (new_blank_lines_at_end--)\n \t\t\t\t\tremove_last_line(&postimage);\n \t\t\t}\n@@ -3005,7 +3010,7 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t\t * apply_patch->check_patch_list->check_patch->\n \t\t\t * apply_data->apply_fragments->apply_one_fragment\n \t\t\t */\n-\t\t\tif (ws_error_action == die_on_ws_error)\n+\t\t\tif (state->ws_error_action == die_on_ws_error)\n \t\t\t\tstate->apply = 0;\n \t\t}\n \n@@ -4543,7 +4548,7 @@ static int apply_patch(struct apply_state *state,\n \tif (!list && !skipped_patch)\n \t\tdie(_(\"unrecognized input\"));\n \n-\tif (state->whitespace_error && (ws_error_action == die_on_ws_error))\n+\tif (state->whitespace_error && (state->ws_error_action == die_on_ws_error))\n \t\tstate->apply = 0;\n \n \tstate->update_index = state->check_index && state->apply;\n@@ -4736,6 +4741,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.p_value = 1;\n \tstate.p_context = UINT_MAX;\n \tstate.squelch_whitespace_errors = 5;\n+\tstate.ws_error_action = warn_on_ws_error;\n \tstrbuf_init(&state.root, 0);\n \n \tgit_apply_config();\n@@ -4804,7 +4810,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t\t\t   squelched),\n \t\t\t\tsquelched);\n \t\t}\n-\t\tif (ws_error_action == die_on_ws_error)\n+\t\tif (state.ws_error_action == die_on_ws_error)\n \t\t\tdie(Q_(\"%d line adds whitespace errors.\",\n \t\t\t       \"%d lines add whitespace errors.\",\n \t\t\t       state.whitespace_error),\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280463","messageId":"1457545756-20616-42-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 41/48] builtin/apply: move 'ws_ignore_action' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:09Z","receivedAt":"2016-03-09T17:49:09Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 37 ++++++++++++++++++++-----------------\n 1 file changed, 20 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex d427c3c..dbb9f0b 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -28,6 +28,12 @@ enum ws_error_action {\n \tcorrect_ws_error\n };\n \n+\n+enum ws_ignore {\n+\tignore_ws_none,\n+\tignore_ws_change\n+};\n+\n struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n@@ -92,6 +98,7 @@ struct apply_state {\n \tint applied_after_fixing_ws;\n \n \tenum ws_error_action ws_error_action;\n+\tenum ws_ignore ws_ignore_action;\n };\n \n static const char * const apply_usage[] = {\n@@ -99,13 +106,6 @@ static const char * const apply_usage[] = {\n \tNULL\n };\n \n-\n-static enum ws_ignore {\n-\tignore_ws_none,\n-\tignore_ws_change\n-} ws_ignore_action = ignore_ws_none;\n-\n-\n static void parse_whitespace_option(struct apply_state *state, const char *option)\n {\n \tif (!option) {\n@@ -136,16 +136,17 @@ static void parse_whitespace_option(struct apply_state *state, const char *optio\n \tdie(_(\"unrecognized whitespace option '%s'\"), option);\n }\n \n-static void parse_ignorewhitespace_option(const char *option)\n+static void parse_ignorewhitespace_option(struct apply_state *state,\n+\t\t\t\t\t  const char *option)\n {\n \tif (!option || !strcmp(option, \"no\") ||\n \t    !strcmp(option, \"false\") || !strcmp(option, \"never\") ||\n \t    !strcmp(option, \"none\")) {\n-\t\tws_ignore_action = ignore_ws_none;\n+\t\tstate->ws_ignore_action = ignore_ws_none;\n \t\treturn;\n \t}\n \tif (!strcmp(option, \"change\")) {\n-\t\tws_ignore_action = ignore_ws_change;\n+\t\tstate->ws_ignore_action = ignore_ws_change;\n \t\treturn;\n \t}\n \tdie(_(\"unrecognized whitespace ignore option '%s'\"), option);\n@@ -2508,7 +2509,7 @@ static int match_fragment(struct apply_state *state,\n \t * fuzzy matching. We collect all the line length information because\n \t * we need it to adjust whitespace if we match.\n \t */\n-\tif (ws_ignore_action == ignore_ws_change) {\n+\tif (state->ws_ignore_action == ignore_ws_change) {\n \t\treturn line_by_line_fuzzy_match(img, preimage, postimage, try, try_lno, preimage_limit);\n \t}\n \n@@ -4625,12 +4626,13 @@ static int option_parse_p(const struct option *opt,\n }\n \n static int option_parse_space_change(const struct option *opt,\n-\t\t\t  const char *arg, int unset)\n+\t\t\t\t     const char *arg, int unset)\n {\n+\tstruct apply_state *state = opt->value;\n \tif (unset)\n-\t\tws_ignore_action = ignore_ws_none;\n+\t\tstate->ws_ignore_action = ignore_ws_none;\n \telse\n-\t\tws_ignore_action = ignore_ws_change;\n+\t\tstate->ws_ignore_action = ignore_ws_change;\n \treturn 0;\n }\n \n@@ -4705,10 +4707,10 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\t{ OPTION_CALLBACK, 0, \"whitespace\", &state, N_(\"action\"),\n \t\t\tN_(\"detect new or modified lines that have whitespace errors\"),\n \t\t\t0, option_parse_whitespace },\n-\t\t{ OPTION_CALLBACK, 0, \"ignore-space-change\", NULL, NULL,\n+\t\t{ OPTION_CALLBACK, 0, \"ignore-space-change\", &state, NULL,\n \t\t\tN_(\"ignore changes in whitespace when finding context\"),\n \t\t\tPARSE_OPT_NOARG, option_parse_space_change },\n-\t\t{ OPTION_CALLBACK, 0, \"ignore-whitespace\", NULL, NULL,\n+\t\t{ OPTION_CALLBACK, 0, \"ignore-whitespace\", &state, NULL,\n \t\t\tN_(\"ignore changes in whitespace when finding context\"),\n \t\t\tPARSE_OPT_NOARG, option_parse_space_change },\n \t\tOPT_BOOL('R', \"reverse\", &state.apply_in_reverse,\n@@ -4742,13 +4744,14 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.p_context = UINT_MAX;\n \tstate.squelch_whitespace_errors = 5;\n \tstate.ws_error_action = warn_on_ws_error;\n+\tstate.ws_ignore_action = ignore_ws_none;\n \tstrbuf_init(&state.root, 0);\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n \t\tparse_whitespace_option(&state, apply_default_whitespace);\n \tif (apply_default_ignorewhitespace)\n-\t\tparse_ignorewhitespace_option(apply_default_ignorewhitespace);\n+\t\tparse_ignorewhitespace_option(&state, apply_default_ignorewhitespace);\n \n \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280464","messageId":"1457545756-20616-43-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 42/48] builtin/apply: move 'max_change' and 'max_len' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:10Z","receivedAt":"2016-03-09T17:49:10Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 49 +++++++++++++++++++++++++------------------------\n 1 file changed, 25 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex dbb9f0b..79224fd 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -79,6 +79,14 @@ struct apply_state {\n \n \tint line_termination;\n \n+\t/*\n+\t * For \"diff-stat\" like behaviour, we keep track of the biggest change\n+\t * we've seen, and the longest filename. That allows us to do simple\n+\t * scaling.\n+\t */\n+\tint max_change;\n+\tint max_len;\n+\n \tint p_value;\n \tint p_value_known;\n \tunsigned int p_context;\n@@ -159,13 +167,6 @@ static void set_default_whitespace_mode(struct apply_state *state)\n }\n \n /*\n- * For \"diff-stat\" like behaviour, we keep track of the biggest change\n- * we've seen, and the longest filename. That allows us to do simple\n- * scaling.\n- */\n-static int max_change, max_len;\n-\n-/*\n  * Various \"current state\", notably line numbers and what\n  * file (and how) we're patching right now.. The \"is_xxxx\"\n  * things are flags, where -1 means \"don't know yet\".\n@@ -2191,7 +2192,7 @@ static const char pluses[] =\n static const char minuses[]=\n \"----------------------------------------------------------------------\";\n \n-static void show_stats(struct patch *patch)\n+static void show_stats(struct apply_state *state, struct patch *patch)\n {\n \tstruct strbuf qname = STRBUF_INIT;\n \tchar *cp = patch->new_name ? patch->new_name : patch->old_name;\n@@ -2202,7 +2203,7 @@ static void show_stats(struct patch *patch)\n \t/*\n \t * \"scale\" the filename\n \t */\n-\tmax = max_len;\n+\tmax = state->max_len;\n \tif (max > 50)\n \t\tmax = 50;\n \n@@ -2225,13 +2226,13 @@ static void show_stats(struct patch *patch)\n \t/*\n \t * scale the add/delete\n \t */\n-\tmax = max + max_change > 70 ? 70 - max : max_change;\n+\tmax = max + state->max_change > 70 ? 70 - max : state->max_change;\n \tadd = patch->lines_added;\n \tdel = patch->lines_deleted;\n \n-\tif (max_change > 0) {\n-\t\tint total = ((add + del) * max + max_change / 2) / max_change;\n-\t\tadd = (add * max + max_change / 2) / max_change;\n+\tif (state->max_change > 0) {\n+\t\tint total = ((add + del) * max + state->max_change / 2) / state->max_change;\n+\t\tadd = (add * max + state->max_change / 2) / state->max_change;\n \t\tdel = total - add;\n \t}\n \tprintf(\"%5d %.*s%.*s\\n\", patch->lines_added + patch->lines_deleted,\n@@ -4058,7 +4059,7 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n \tdiscard_index(&result);\n }\n \n-static void stat_patch_list(struct patch *patch)\n+static void stat_patch_list(struct apply_state *state, struct patch *patch)\n {\n \tint files, adds, dels;\n \n@@ -4066,7 +4067,7 @@ static void stat_patch_list(struct patch *patch)\n \t\tfiles++;\n \t\tadds += patch->lines_added;\n \t\tdels += patch->lines_deleted;\n-\t\tshow_stats(patch);\n+\t\tshow_stats(state, patch);\n \t}\n \n \tprint_stat_summary(stdout, files, adds, dels);\n@@ -4164,25 +4165,25 @@ static void summary_patch_list(struct patch *patch)\n \t}\n }\n \n-static void patch_stats(struct patch *patch)\n+static void patch_stats(struct apply_state *state, struct patch *patch)\n {\n \tint lines = patch->lines_added + patch->lines_deleted;\n \n-\tif (lines > max_change)\n-\t\tmax_change = lines;\n+\tif (lines > state->max_change)\n+\t\tstate->max_change = lines;\n \tif (patch->old_name) {\n \t\tint len = quote_c_style(patch->old_name, NULL, NULL, 0);\n \t\tif (!len)\n \t\t\tlen = strlen(patch->old_name);\n-\t\tif (len > max_len)\n-\t\t\tmax_len = len;\n+\t\tif (len > state->max_len)\n+\t\t\tstate->max_len = len;\n \t}\n \tif (patch->new_name) {\n \t\tint len = quote_c_style(patch->new_name, NULL, NULL, 0);\n \t\tif (!len)\n \t\t\tlen = strlen(patch->new_name);\n-\t\tif (len > max_len)\n-\t\t\tmax_len = len;\n+\t\tif (len > state->max_len)\n+\t\t\tstate->max_len = len;\n \t}\n }\n \n@@ -4535,7 +4536,7 @@ static int apply_patch(struct apply_state *state,\n \t\tif (state->apply_in_reverse)\n \t\t\treverse_patches(patch);\n \t\tif (use_patch(state, patch)) {\n-\t\t\tpatch_stats(patch);\n+\t\t\tpatch_stats(state, patch);\n \t\t\t*listp = patch;\n \t\t\tlistp = &patch->next;\n \t\t}\n@@ -4577,7 +4578,7 @@ static int apply_patch(struct apply_state *state,\n \t\tbuild_fake_ancestor(list, state->fake_ancestor);\n \n \tif (state->diffstat)\n-\t\tstat_patch_list(list);\n+\t\tstat_patch_list(state, list);\n \n \tif (state->numstat)\n \t\tnumstat_patch_list(state, list);\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280468","messageId":"1457545756-20616-44-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 43/48] builtin/apply: move 'linenr' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:11Z","receivedAt":"2016-03-09T17:49:11Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 75 ++++++++++++++++++++++++++++++---------------------------\n 1 file changed, 40 insertions(+), 35 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 79224fd..3808d60 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -87,6 +87,13 @@ struct apply_state {\n \tint max_change;\n \tint max_len;\n \n+\t/*\n+\t * Various \"current state\", notably line numbers and what\n+\t * file (and how) we're patching right now.. The \"is_xxxx\"\n+\t * things are flags, where -1 means \"don't know yet\".\n+\t */\n+\tint linenr;\n+\n \tint p_value;\n \tint p_value_known;\n \tunsigned int p_context;\n@@ -167,13 +174,6 @@ static void set_default_whitespace_mode(struct apply_state *state)\n }\n \n /*\n- * Various \"current state\", notably line numbers and what\n- * file (and how) we're patching right now.. The \"is_xxxx\"\n- * things are flags, where -1 means \"don't know yet\".\n- */\n-static int linenr = 1;\n-\n-/*\n  * This represents one \"hunk\" from a patch, starting with\n  * \"@@ -oldpos,oldlines +newpos,newlines @@\" marker.  The\n  * patch text is pointed at by patch, and its byte length\n@@ -949,7 +949,7 @@ static void parse_traditional_patch(struct apply_state *state,\n \t\t}\n \t}\n \tif (!name)\n-\t\tdie(_(\"unable to find filename in patch at line %d\"), linenr);\n+\t\tdie(_(\"unable to find filename in patch at line %d\"), state->linenr);\n }\n \n static int gitdiff_hdrend(struct apply_state *state,\n@@ -987,19 +987,19 @@ static char *gitdiff_verify_name(struct apply_state *state,\n \t\tname = orig_name;\n \t\tlen = strlen(name);\n \t\tif (isnull)\n-\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, linenr);\n+\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"), name, state->linenr);\n \t\tanother = find_name(state, line, NULL, state->p_value, TERM_TAB);\n \t\tif (!another || memcmp(another, name, len + 1))\n \t\t\tdie((side == DIFF_NEW_NAME) ?\n \t\t\t    _(\"git apply: bad git-diff - inconsistent new filename on line %d\") :\n-\t\t\t    _(\"git apply: bad git-diff - inconsistent old filename on line %d\"), linenr);\n+\t\t\t    _(\"git apply: bad git-diff - inconsistent old filename on line %d\"), state->linenr);\n \t\tfree(another);\n \t\treturn orig_name;\n \t}\n \telse {\n \t\t/* expect \"/dev/null\" */\n \t\tif (memcmp(\"/dev/null\", line, 9) || line[9] != '\\n')\n-\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null on line %d\"), linenr);\n+\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null on line %d\"), state->linenr);\n \t\treturn NULL;\n \t}\n }\n@@ -1369,8 +1369,8 @@ static int parse_git_header(struct apply_state *state,\n \n \tline += len;\n \tsize -= len;\n-\tlinenr++;\n-\tfor (offset = len ; size > 0 ; offset += len, size -= len, line += len, linenr++) {\n+\tstate->linenr++;\n+\tfor (offset = len ; size > 0 ; offset += len, size -= len, line += len, state->linenr++) {\n \t\tstatic const struct opentry {\n \t\t\tconst char *str;\n \t\t\tint (*fn)(struct apply_state *, const char *, struct patch *);\n@@ -1541,7 +1541,7 @@ static int find_header(struct apply_state *state,\n \tpatch->is_new = patch->is_delete = -1;\n \tpatch->old_mode = patch->new_mode = 0;\n \tpatch->old_name = patch->new_name = NULL;\n-\tfor (offset = 0; size > 0; offset += len, size -= len, line += len, linenr++) {\n+\tfor (offset = 0; size > 0; offset += len, size -= len, line += len, state->linenr++) {\n \t\tunsigned long nextlen;\n \n \t\tlen = linelen(line, size);\n@@ -1562,7 +1562,7 @@ static int find_header(struct apply_state *state,\n \t\t\tif (parse_fragment_header(line, len, &dummy) < 0)\n \t\t\t\tcontinue;\n \t\t\tdie(_(\"patch fragment without header at line %d: %.*s\"),\n-\t\t\t    linenr, (int)len-1, line);\n+\t\t\t    state->linenr, (int)len-1, line);\n \t\t}\n \n \t\tif (size < len + 6)\n@@ -1583,13 +1583,13 @@ static int find_header(struct apply_state *state,\n \t\t\t\t\t       \"git diff header lacks filename information when removing \"\n \t\t\t\t\t       \"%d leading pathname components (line %d)\",\n \t\t\t\t\t       state->p_value),\n-\t\t\t\t\t    state->p_value, linenr);\n+\t\t\t\t\t    state->p_value, state->linenr);\n \t\t\t\tpatch->old_name = xstrdup(patch->def_name);\n \t\t\t\tpatch->new_name = xstrdup(patch->def_name);\n \t\t\t}\n \t\t\tif (!patch->is_delete && !patch->new_name)\n \t\t\t\tdie(\"git diff header lacks filename information \"\n-\t\t\t\t    \"(line %d)\", linenr);\n+\t\t\t\t    \"(line %d)\", state->linenr);\n \t\t\tpatch->is_toplevel_relative = 1;\n \t\t\t*hdrsize = git_hdr_len;\n \t\t\treturn offset;\n@@ -1611,7 +1611,7 @@ static int find_header(struct apply_state *state,\n \t\t/* Ok, we'll consider it a patch */\n \t\tparse_traditional_patch(state, line, line+len, patch);\n \t\t*hdrsize = len + nextlen;\n-\t\tlinenr += 2;\n+\t\tstate->linenr += 2;\n \t\treturn offset;\n \t}\n \treturn -1;\n@@ -1646,7 +1646,7 @@ static void check_whitespace(struct apply_state *state,\n {\n \tunsigned result = ws_check(line + 1, len - 1, ws_rule);\n \n-\trecord_ws_error(state, result, line + 1, len - 2, linenr);\n+\trecord_ws_error(state, result, line + 1, len - 2, state->linenr);\n }\n \n /*\n@@ -1679,11 +1679,11 @@ static int parse_fragment(struct apply_state *state,\n \t/* Parse the thing.. */\n \tline += len;\n \tsize -= len;\n-\tlinenr++;\n+\tstate->linenr++;\n \tadded = deleted = 0;\n \tfor (offset = len;\n \t     0 < size;\n-\t     offset += len, size -= len, line += len, linenr++) {\n+\t     offset += len, size -= len, line += len, state->linenr++) {\n \t\tif (!oldlines && !newlines)\n \t\t\tbreak;\n \t\tlen = linelen(line, size);\n@@ -1782,10 +1782,10 @@ static int parse_single_patch(struct apply_state *state,\n \t\tint len;\n \n \t\tfragment = xcalloc(1, sizeof(*fragment));\n-\t\tfragment->linenr = linenr;\n+\t\tfragment->linenr = state->linenr;\n \t\tlen = parse_fragment(state, line, size, patch, fragment);\n \t\tif (len <= 0)\n-\t\t\tdie(_(\"corrupt patch at line %d\"), linenr);\n+\t\t\tdie(_(\"corrupt patch at line %d\"), state->linenr);\n \t\tfragment->patch = line;\n \t\tfragment->size = len;\n \t\toldlines += fragment->oldlines;\n@@ -1871,7 +1871,8 @@ static char *inflate_it(const void *data, unsigned long size,\n  * points at an allocated memory that the caller must free, so\n  * it is marked as \"->free_patch = 1\".\n  */\n-static struct fragment *parse_binary_hunk(char **buf_p,\n+static struct fragment *parse_binary_hunk(struct apply_state *state,\n+\t\t\t\t\t  char **buf_p,\n \t\t\t\t\t  unsigned long *sz_p,\n \t\t\t\t\t  int *status_p,\n \t\t\t\t\t  int *used_p)\n@@ -1913,13 +1914,13 @@ static struct fragment *parse_binary_hunk(char **buf_p,\n \telse\n \t\treturn NULL;\n \n-\tlinenr++;\n+\tstate->linenr++;\n \tbuffer += llen;\n \twhile (1) {\n \t\tint byte_length, max_byte_length, newsize;\n \t\tllen = linelen(buffer, size);\n \t\tused += llen;\n-\t\tlinenr++;\n+\t\tstate->linenr++;\n \t\tif (llen == 1) {\n \t\t\t/* consume the blank line */\n \t\t\tbuffer++;\n@@ -1973,11 +1974,14 @@ static struct fragment *parse_binary_hunk(char **buf_p,\n \tfree(data);\n \t*status_p = -1;\n \terror(_(\"corrupt binary patch at line %d: %.*s\"),\n-\t      linenr-1, llen-1, buffer);\n+\t      state->linenr-1, llen-1, buffer);\n \treturn NULL;\n }\n \n-static int parse_binary(char *buffer, unsigned long size, struct patch *patch)\n+static int parse_binary(struct apply_state *state,\n+\t\t\tchar *buffer,\n+\t\t\tunsigned long size,\n+\t\t\tstruct patch *patch)\n {\n \t/*\n \t * We have read \"GIT binary patch\\n\"; what follows is a line\n@@ -1998,15 +2002,15 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)\n \tint status;\n \tint used, used_1;\n \n-\tforward = parse_binary_hunk(&buffer, &size, &status, &used);\n+\tforward = parse_binary_hunk(state, &buffer, &size, &status, &used);\n \tif (!forward && !status)\n \t\t/* there has to be one hunk (forward hunk) */\n-\t\treturn error(_(\"unrecognized binary patch at line %d\"), linenr-1);\n+\t\treturn error(_(\"unrecognized binary patch at line %d\"), state->linenr-1);\n \tif (status)\n \t\t/* otherwise we already gave an error message */\n \t\treturn status;\n \n-\treverse = parse_binary_hunk(&buffer, &size, &status, &used_1);\n+\treverse = parse_binary_hunk(state, &buffer, &size, &status, &used_1);\n \tif (reverse)\n \t\tused += used_1;\n \telse if (status) {\n@@ -2121,8 +2125,8 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\tif (llen == sizeof(git_binary) - 1 &&\n \t\t    !memcmp(git_binary, buffer + hd, llen)) {\n \t\t\tint used;\n-\t\t\tlinenr++;\n-\t\t\tused = parse_binary(buffer + hd + llen,\n+\t\t\tstate->linenr++;\n+\t\t\tused = parse_binary(state, buffer + hd + llen,\n \t\t\t\t\t    size - hd - llen, patch);\n \t\t\tif (used)\n \t\t\t\tpatchsize = used + llen;\n@@ -2140,7 +2144,7 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\t\t\tint len = strlen(binhdr[i]);\n \t\t\t\tif (len < size - hd &&\n \t\t\t\t    !memcmp(binhdr[i], buffer + hd, len)) {\n-\t\t\t\t\tlinenr++;\n+\t\t\t\t\tstate->linenr++;\n \t\t\t\t\tpatch->is_binary = 1;\n \t\t\t\t\tpatchsize = llen;\n \t\t\t\t\tbreak;\n@@ -2154,7 +2158,7 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\t */\n \t\tif ((state->apply || state->check) &&\n \t\t    (!patch->is_binary && !metadata_changes(patch)))\n-\t\t\tdie(_(\"patch with only garbage at line %d\"), linenr);\n+\t\t\tdie(_(\"patch with only garbage at line %d\"), state->linenr);\n \t}\n \n \treturn offset + hdrsize + patchsize;\n@@ -4746,6 +4750,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \tstate.squelch_whitespace_errors = 5;\n \tstate.ws_error_action = warn_on_ws_error;\n \tstate.ws_ignore_action = ignore_ws_none;\n+\tstate.linenr = 1;\n \tstrbuf_init(&state.root, 0);\n \n \tgit_apply_config();\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280466","messageId":"1457545756-20616-45-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 44/48] builtin/apply: move 'fn_table' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:12Z","receivedAt":"2016-03-09T17:49:12Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 45 +++++++++++++++++++++++----------------------\n 1 file changed, 23 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 3808d60..8fda1bd 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -94,6 +94,12 @@ struct apply_state {\n \t */\n \tint linenr;\n \n+\t/*\n+\t * Records filenames that have been touched, in order to handle\n+\t * the case where more than one patches touch the same file.\n+\t */\n+\tstruct string_list fn_table;\n+\n \tint p_value;\n \tint p_value_known;\n \tunsigned int p_context;\n@@ -292,13 +298,6 @@ struct image {\n \tstruct line *line;\n };\n \n-/*\n- * Records filenames that have been touched, in order to handle\n- * the case where more than one patches touch the same file.\n- */\n-\n-static struct string_list fn_table;\n-\n static uint32_t hash_line(const char *cp, size_t len)\n {\n \tsize_t i;\n@@ -3231,14 +3230,14 @@ static int read_file_or_gitlink(const struct cache_entry *ce, struct strbuf *buf\n \treturn read_blob_object(buf, ce->sha1, ce->ce_mode);\n }\n \n-static struct patch *in_fn_table(const char *name)\n+static struct patch *in_fn_table(struct apply_state *state, const char *name)\n {\n \tstruct string_list_item *item;\n \n \tif (name == NULL)\n \t\treturn NULL;\n \n-\titem = string_list_lookup(&fn_table, name);\n+\titem = string_list_lookup(&state->fn_table, name);\n \tif (item != NULL)\n \t\treturn (struct patch *)item->util;\n \n@@ -3270,7 +3269,7 @@ static int was_deleted(struct patch *patch)\n \treturn patch == PATH_WAS_DELETED;\n }\n \n-static void add_to_fn_table(struct patch *patch)\n+static void add_to_fn_table(struct apply_state *state, struct patch *patch)\n {\n \tstruct string_list_item *item;\n \n@@ -3280,7 +3279,7 @@ static void add_to_fn_table(struct patch *patch)\n \t * file creations and copies\n \t */\n \tif (patch->new_name != NULL) {\n-\t\titem = string_list_insert(&fn_table, patch->new_name);\n+\t\titem = string_list_insert(&state->fn_table, patch->new_name);\n \t\titem->util = patch;\n \t}\n \n@@ -3289,12 +3288,12 @@ static void add_to_fn_table(struct patch *patch)\n \t * later chunks shouldn't patch old names\n \t */\n \tif ((patch->new_name == NULL) || (patch->is_rename)) {\n-\t\titem = string_list_insert(&fn_table, patch->old_name);\n+\t\titem = string_list_insert(&state->fn_table, patch->old_name);\n \t\titem->util = PATH_WAS_DELETED;\n \t}\n }\n \n-static void prepare_fn_table(struct patch *patch)\n+static void prepare_fn_table(struct apply_state *state, struct patch *patch)\n {\n \t/*\n \t * store information about incoming file deletion\n@@ -3302,7 +3301,7 @@ static void prepare_fn_table(struct patch *patch)\n \twhile (patch) {\n \t\tif ((patch->new_name == NULL) || (patch->is_rename)) {\n \t\t\tstruct string_list_item *item;\n-\t\t\titem = string_list_insert(&fn_table, patch->old_name);\n+\t\t\titem = string_list_insert(&state->fn_table, patch->old_name);\n \t\t\titem->util = PATH_TO_BE_DELETED;\n \t\t}\n \t\tpatch = patch->next;\n@@ -3323,7 +3322,9 @@ static int checkout_target(struct index_state *istate,\n \treturn 0;\n }\n \n-static struct patch *previous_patch(struct patch *patch, int *gone)\n+static struct patch *previous_patch(struct apply_state *state,\n+\t\t\t\t    struct patch *patch,\n+\t\t\t\t    int *gone)\n {\n \tstruct patch *previous;\n \n@@ -3331,7 +3332,7 @@ static struct patch *previous_patch(struct patch *patch, int *gone)\n \tif (patch->is_copy || patch->is_rename)\n \t\treturn NULL; /* \"git\" patches do not depend on the order */\n \n-\tprevious = in_fn_table(patch->old_name);\n+\tprevious = in_fn_table(state, patch->old_name);\n \tif (!previous)\n \t\treturn NULL;\n \n@@ -3400,7 +3401,7 @@ static int load_preimage(struct apply_state *state,\n \tstruct patch *previous;\n \tint status;\n \n-\tprevious = previous_patch(patch, &status);\n+\tprevious = previous_patch(state, patch, &status);\n \tif (status)\n \t\treturn error(_(\"path %s has been renamed/deleted\"),\n \t\t\t     patch->old_name);\n@@ -3596,7 +3597,7 @@ static int apply_data(struct apply_state *state, struct patch *patch,\n \t}\n \tpatch->result = image.buf;\n \tpatch->resultsize = image.len;\n-\tadd_to_fn_table(patch);\n+\tadd_to_fn_table(state, patch);\n \tfree(image.line_allocated);\n \n \tif (0 < patch->is_delete && patch->resultsize)\n@@ -3630,7 +3631,7 @@ static int check_preimage(struct apply_state *state,\n \t\treturn 0;\n \n \tassert(patch->is_new <= 0);\n-\tprevious = previous_patch(patch, &status);\n+\tprevious = previous_patch(state, patch, &status);\n \n \tif (status)\n \t\treturn error(_(\"path %s has been renamed/deleted\"), old_name);\n@@ -3876,7 +3877,7 @@ static int check_patch(struct apply_state *state, struct patch *patch)\n \t * B and rename from A to B is handled the same way by asking\n \t * was_deleted().\n \t */\n-\tif ((tpatch = in_fn_table(new_name)) &&\n+\tif ((tpatch = in_fn_table(state, new_name)) &&\n \t    (was_deleted(tpatch) || to_be_deleted(tpatch)))\n \t\tok_if_exists = 1;\n \telse\n@@ -3954,7 +3955,7 @@ static int check_patch_list(struct apply_state *state, struct patch *patch)\n \tint err = 0;\n \n \tprepare_symlink_changes(patch);\n-\tprepare_fn_table(patch);\n+\tprepare_fn_table(state, patch);\n \twhile (patch) {\n \t\tif (state->apply_verbosely)\n \t\t\tsay_patch_name(stderr,\n@@ -4592,7 +4593,7 @@ static int apply_patch(struct apply_state *state,\n \n \tfree_patch_list(list);\n \tstrbuf_release(&buf);\n-\tstring_list_clear(&fn_table, 0);\n+\tstring_list_clear(&state->fn_table, 0);\n \treturn 0;\n }\n \n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280469","messageId":"1457545756-20616-46-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 45/48] builtin/apply: move 'symlink_changes' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:13Z","receivedAt":"2016-03-09T17:49:13Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 50 ++++++++++++++++++++++++++++----------------------\n 1 file changed, 28 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 8fda1bd..66ebc9b 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -34,6 +34,20 @@ enum ws_ignore {\n \tignore_ws_change\n };\n \n+/*\n+ * We need to keep track of how symlinks in the preimage are\n+ * manipulated by the patches.  A patch to add a/b/c where a/b\n+ * is a symlink should not be allowed to affect the directory\n+ * the symlink points at, but if the same patch removes a/b,\n+ * it is perfectly fine, as the patch removes a/b to make room\n+ * to create a directory a/b so that a/b/c can be created.\n+ *\n+ * See also \"struct string_list symlink_changes\" in \"struct\n+ * apply_state\".\n+ */\n+#define SYMLINK_GOES_AWAY 01\n+#define SYMLINK_IN_RESULT 02\n+\n struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n@@ -100,6 +114,8 @@ struct apply_state {\n \t */\n \tstruct string_list fn_table;\n \n+\tstruct string_list symlink_changes;\n+\n \tint p_value;\n \tint p_value_known;\n \tunsigned int p_context;\n@@ -3726,52 +3742,42 @@ static int check_to_create(struct apply_state *state,\n \treturn 0;\n }\n \n-/*\n- * We need to keep track of how symlinks in the preimage are\n- * manipulated by the patches.  A patch to add a/b/c where a/b\n- * is a symlink should not be allowed to affect the directory\n- * the symlink points at, but if the same patch removes a/b,\n- * it is perfectly fine, as the patch removes a/b to make room\n- * to create a directory a/b so that a/b/c can be created.\n- */\n-static struct string_list symlink_changes;\n-#define SYMLINK_GOES_AWAY 01\n-#define SYMLINK_IN_RESULT 02\n-\n-static uintptr_t register_symlink_changes(const char *path, uintptr_t what)\n+static uintptr_t register_symlink_changes(struct apply_state *state,\n+\t\t\t\t\t  const char *path,\n+\t\t\t\t\t  uintptr_t what)\n {\n \tstruct string_list_item *ent;\n \n-\tent = string_list_lookup(&symlink_changes, path);\n+\tent = string_list_lookup(&state->symlink_changes, path);\n \tif (!ent) {\n-\t\tent = string_list_insert(&symlink_changes, path);\n+\t\tent = string_list_insert(&state->symlink_changes, path);\n \t\tent->util = (void *)0;\n \t}\n \tent->util = (void *)(what | ((uintptr_t)ent->util));\n \treturn (uintptr_t)ent->util;\n }\n \n-static uintptr_t check_symlink_changes(const char *path)\n+static uintptr_t check_symlink_changes(struct apply_state *state, const char *path)\n {\n \tstruct string_list_item *ent;\n \n-\tent = string_list_lookup(&symlink_changes, path);\n+\tent = string_list_lookup(&state->symlink_changes, path);\n \tif (!ent)\n \t\treturn 0;\n \treturn (uintptr_t)ent->util;\n }\n \n-static void prepare_symlink_changes(struct patch *patch)\n+static void prepare_symlink_changes(struct apply_state *state, struct patch *patch)\n {\n \tfor ( ; patch; patch = patch->next) {\n \t\tif ((patch->old_name && S_ISLNK(patch->old_mode)) &&\n \t\t    (patch->is_rename || patch->is_delete))\n \t\t\t/* the symlink at patch->old_name is removed */\n-\t\t\tregister_symlink_changes(patch->old_name, SYMLINK_GOES_AWAY);\n+\t\t\tregister_symlink_changes(state, patch->old_name, SYMLINK_GOES_AWAY);\n \n \t\tif (patch->new_name && S_ISLNK(patch->new_mode))\n \t\t\t/* the symlink at patch->new_name is created or remains */\n-\t\t\tregister_symlink_changes(patch->new_name, SYMLINK_IN_RESULT);\n+\t\t\tregister_symlink_changes(state, patch->new_name, SYMLINK_IN_RESULT);\n \t}\n }\n \n@@ -3785,7 +3791,7 @@ static int path_is_beyond_symlink_1(struct apply_state *state, struct strbuf *na\n \t\tif (!name->len)\n \t\t\tbreak;\n \t\tname->buf[name->len] = '\\0';\n-\t\tchange = check_symlink_changes(name->buf);\n+\t\tchange = check_symlink_changes(state, name->buf);\n \t\tif (change & SYMLINK_IN_RESULT)\n \t\t\treturn 1;\n \t\tif (change & SYMLINK_GOES_AWAY)\n@@ -3954,7 +3960,7 @@ static int check_patch_list(struct apply_state *state, struct patch *patch)\n {\n \tint err = 0;\n \n-\tprepare_symlink_changes(patch);\n+\tprepare_symlink_changes(state, patch);\n \tprepare_fn_table(state, patch);\n \twhile (patch) {\n \t\tif (state->apply_verbosely)\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280467","messageId":"1457545756-20616-47-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 46/48] builtin/apply: move 'state' init into init_apply_state()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:14Z","receivedAt":"2016-03-09T17:49:14Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 43 ++++++++++++++++++++++++-------------------\n 1 file changed, 24 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 66ebc9b..1676ce1 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4667,6 +4667,29 @@ static int option_parse_directory(const struct option *opt,\n \treturn 0;\n }\n \n+static void init_apply_state(struct apply_state *state, const char *prefix_)\n+{\n+\tmemset(state, 0, sizeof(*state));\n+\tstate->prefix = prefix_;\n+\tstate->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n+\tstate->apply = 1;\n+\tstate->newfd = -1;\n+\tstate->line_termination = '\\n';\n+\tstate->p_value = 1;\n+\tstate->p_context = UINT_MAX;\n+\tstate->squelch_whitespace_errors = 5;\n+\tstate->ws_error_action = warn_on_ws_error;\n+\tstate->ws_ignore_action = ignore_ws_none;\n+\tstate->linenr = 1;\n+\tstrbuf_init(&state->root, 0);\n+\n+\tgit_apply_config();\n+\tif (apply_default_whitespace)\n+\t\tparse_whitespace_option(state, apply_default_whitespace);\n+\tif (apply_default_ignorewhitespace)\n+\t\tparse_ignorewhitespace_option(state, apply_default_ignorewhitespace);\n+}\n+\n int cmd_apply(int argc, const char **argv, const char *prefix_)\n {\n \tint i;\n@@ -4746,25 +4769,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tOPT_END()\n \t};\n \n-\tmemset(&state, 0, sizeof(state));\n-\tstate.prefix = prefix_;\n-\tstate.prefix_length = state.prefix ? strlen(state.prefix) : 0;\n-\tstate.apply = 1;\n-\tstate.newfd = -1;\n-\tstate.line_termination = '\\n';\n-\tstate.p_value = 1;\n-\tstate.p_context = UINT_MAX;\n-\tstate.squelch_whitespace_errors = 5;\n-\tstate.ws_error_action = warn_on_ws_error;\n-\tstate.ws_ignore_action = ignore_ws_none;\n-\tstate.linenr = 1;\n-\tstrbuf_init(&state.root, 0);\n-\n-\tgit_apply_config();\n-\tif (apply_default_whitespace)\n-\t\tparse_whitespace_option(&state, apply_default_whitespace);\n-\tif (apply_default_ignorewhitespace)\n-\t\tparse_ignorewhitespace_option(&state, apply_default_ignorewhitespace);\n+\tinit_apply_state(&state, prefix_);\n \n \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280470","messageId":"1457545756-20616-48-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 47/48] builtin/apply: move 'state' check into check_apply_state()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:15Z","receivedAt":"2016-03-09T17:49:15Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 52 +++++++++++++++++++++++++++++-----------------------\n 1 file changed, 29 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 1676ce1..3f76469 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4690,11 +4690,38 @@ static void init_apply_state(struct apply_state *state, const char *prefix_)\n \t\tparse_ignorewhitespace_option(state, apply_default_ignorewhitespace);\n }\n \n+static void check_apply_state(struct apply_state *state, int force_apply)\n+{\n+\tint is_not_gitdir = !startup_info->have_repository;\n+\n+\tif (state->apply_with_reject && state->threeway)\n+\t\tdie(\"--reject and --3way cannot be used together.\");\n+\tif (state->cached && state->threeway)\n+\t\tdie(\"--cached and --3way cannot be used together.\");\n+\tif (state->threeway) {\n+\t\tif (is_not_gitdir)\n+\t\t\tdie(_(\"--3way outside a repository\"));\n+\t\tstate->check_index = 1;\n+\t}\n+\tif (state->apply_with_reject)\n+\t\tstate->apply = state->apply_verbosely = 1;\n+\tif (!force_apply && (state->diffstat || state->numstat || state->summary || state->check || state->fake_ancestor))\n+\t\tstate->apply = 0;\n+\tif (state->check_index && is_not_gitdir)\n+\t\tdie(_(\"--index outside a repository\"));\n+\tif (state->cached) {\n+\t\tif (is_not_gitdir)\n+\t\t\tdie(_(\"--cached outside a repository\"));\n+\t\tstate->check_index = 1;\n+\t}\n+\tif (state->check_index)\n+\t\tstate->unsafe_paths = 0;\n+}\n+\n int cmd_apply(int argc, const char **argv, const char *prefix_)\n {\n \tint i;\n \tint errs = 0;\n-\tint is_not_gitdir = !startup_info->have_repository;\n \tint force_apply = 0;\n \tint options = 0;\n \tint read_stdin = 1;\n@@ -4774,28 +4801,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n \n-\tif (state.apply_with_reject && state.threeway)\n-\t\tdie(\"--reject and --3way cannot be used together.\");\n-\tif (state.cached && state.threeway)\n-\t\tdie(\"--cached and --3way cannot be used together.\");\n-\tif (state.threeway) {\n-\t\tif (is_not_gitdir)\n-\t\t\tdie(_(\"--3way outside a repository\"));\n-\t\tstate.check_index = 1;\n-\t}\n-\tif (state.apply_with_reject)\n-\t\tstate.apply = state.apply_verbosely = 1;\n-\tif (!force_apply && (state.diffstat || state.numstat || state.summary || state.check || state.fake_ancestor))\n-\t\tstate.apply = 0;\n-\tif (state.check_index && is_not_gitdir)\n-\t\tdie(_(\"--index outside a repository\"));\n-\tif (state.cached) {\n-\t\tif (is_not_gitdir)\n-\t\t\tdie(_(\"--cached outside a repository\"));\n-\t\tstate.check_index = 1;\n-\t}\n-\tif (state.check_index)\n-\t\tstate.unsafe_paths = 0;\n+\tcheck_apply_state(&state, force_apply);\n \n \tfor (i = 0; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280471","messageId":"1457545756-20616-49-git-send-email-chriscool@tuxfamily.org","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"[RFC/PATCH 48/48] builtin/apply: move applying patches into apply_all_patches()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-09T17:49:16Z","receivedAt":"2016-03-09T17:49:16Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 128 ++++++++++++++++++++++++++++++--------------------------\n 1 file changed, 69 insertions(+), 59 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 3f76469..9611b1a 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4718,13 +4718,79 @@ static void check_apply_state(struct apply_state *state, int force_apply)\n \t\tstate->unsafe_paths = 0;\n }\n \n-int cmd_apply(int argc, const char **argv, const char *prefix_)\n+static int apply_all_patches(struct apply_state *state,\n+\t\t\t     int argc,\n+\t\t\t     const char **argv,\n+\t\t\t     int options)\n {\n \tint i;\n \tint errs = 0;\n+\tint read_stdin = 1;\n+\n+\tfor (i = 0; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n+\t\tint fd;\n+\n+\t\tif (!strcmp(arg, \"-\")) {\n+\t\t\terrs |= apply_patch(state, 0, \"<stdin>\", options);\n+\t\t\tread_stdin = 0;\n+\t\t\tcontinue;\n+\t\t} else if (0 < state->prefix_length)\n+\t\t\targ = prefix_filename(state->prefix,\n+\t\t\t\t\t      state->prefix_length,\n+\t\t\t\t\t      arg);\n+\n+\t\tfd = open(arg, O_RDONLY);\n+\t\tif (fd < 0)\n+\t\t\tdie_errno(_(\"can't open patch '%s'\"), arg);\n+\t\tread_stdin = 0;\n+\t\tset_default_whitespace_mode(state);\n+\t\terrs |= apply_patch(state, fd, arg, options);\n+\t\tclose(fd);\n+\t}\n+\tset_default_whitespace_mode(state);\n+\tif (read_stdin)\n+\t\terrs |= apply_patch(state, 0, \"<stdin>\", options);\n+\n+\tif (state->whitespace_error) {\n+\t\tif (state->squelch_whitespace_errors &&\n+\t\t    state->squelch_whitespace_errors < state->whitespace_error) {\n+\t\t\tint squelched =\n+\t\t\t\tstate->whitespace_error - state->squelch_whitespace_errors;\n+\t\t\twarning(Q_(\"squelched %d whitespace error\",\n+\t\t\t\t   \"squelched %d whitespace errors\",\n+\t\t\t\t   squelched),\n+\t\t\t\tsquelched);\n+\t\t}\n+\t\tif (state->ws_error_action == die_on_ws_error)\n+\t\t\tdie(Q_(\"%d line adds whitespace errors.\",\n+\t\t\t       \"%d lines add whitespace errors.\",\n+\t\t\t       state->whitespace_error),\n+\t\t\t    state->whitespace_error);\n+\t\tif (state->applied_after_fixing_ws && state->apply)\n+\t\t\twarning(\"%d line%s applied after\"\n+\t\t\t\t\" fixing whitespace errors.\",\n+\t\t\t\tstate->applied_after_fixing_ws,\n+\t\t\t\tstate->applied_after_fixing_ws == 1 ? \"\" : \"s\");\n+\t\telse if (state->whitespace_error)\n+\t\t\twarning(Q_(\"%d line adds whitespace errors.\",\n+\t\t\t\t   \"%d lines add whitespace errors.\",\n+\t\t\t\t   state->whitespace_error),\n+\t\t\t\tstate->whitespace_error);\n+\t}\n+\n+\tif (state->update_index) {\n+\t\tif (write_locked_index(&the_index, &state->lock_file, COMMIT_LOCK))\n+\t\t\tdie(_(\"Unable to write new index file\"));\n+\t}\n+\n+\treturn !!errs;\n+}\n+\n+int cmd_apply(int argc, const char **argv, const char *prefix_)\n+{\n \tint force_apply = 0;\n \tint options = 0;\n-\tint read_stdin = 1;\n \tstruct apply_state state;\n \n \tstruct option builtin_apply_options[] = {\n@@ -4803,61 +4869,5 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \n \tcheck_apply_state(&state, force_apply);\n \n-\tfor (i = 0; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\t\tint fd;\n-\n-\t\tif (!strcmp(arg, \"-\")) {\n-\t\t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n-\t\t\tread_stdin = 0;\n-\t\t\tcontinue;\n-\t\t} else if (0 < state.prefix_length)\n-\t\t\targ = prefix_filename(state.prefix,\n-\t\t\t\t\t      state.prefix_length,\n-\t\t\t\t\t      arg);\n-\n-\t\tfd = open(arg, O_RDONLY);\n-\t\tif (fd < 0)\n-\t\t\tdie_errno(_(\"can't open patch '%s'\"), arg);\n-\t\tread_stdin = 0;\n-\t\tset_default_whitespace_mode(&state);\n-\t\terrs |= apply_patch(&state, fd, arg, options);\n-\t\tclose(fd);\n-\t}\n-\tset_default_whitespace_mode(&state);\n-\tif (read_stdin)\n-\t\terrs |= apply_patch(&state, 0, \"<stdin>\", options);\n-\tif (state.whitespace_error) {\n-\t\tif (state.squelch_whitespace_errors &&\n-\t\t    state.squelch_whitespace_errors < state.whitespace_error) {\n-\t\t\tint squelched =\n-\t\t\t\tstate.whitespace_error - state.squelch_whitespace_errors;\n-\t\t\twarning(Q_(\"squelched %d whitespace error\",\n-\t\t\t\t   \"squelched %d whitespace errors\",\n-\t\t\t\t   squelched),\n-\t\t\t\tsquelched);\n-\t\t}\n-\t\tif (state.ws_error_action == die_on_ws_error)\n-\t\t\tdie(Q_(\"%d line adds whitespace errors.\",\n-\t\t\t       \"%d lines add whitespace errors.\",\n-\t\t\t       state.whitespace_error),\n-\t\t\t    state.whitespace_error);\n-\t\tif (state.applied_after_fixing_ws && state.apply)\n-\t\t\twarning(\"%d line%s applied after\"\n-\t\t\t\t\" fixing whitespace errors.\",\n-\t\t\t\tstate.applied_after_fixing_ws,\n-\t\t\t\tstate.applied_after_fixing_ws == 1 ? \"\" : \"s\");\n-\t\telse if (state.whitespace_error)\n-\t\t\twarning(Q_(\"%d line adds whitespace errors.\",\n-\t\t\t\t   \"%d lines add whitespace errors.\",\n-\t\t\t\t   state.whitespace_error),\n-\t\t\t\tstate.whitespace_error);\n-\t}\n-\n-\tif (state.update_index) {\n-\t\tif (write_locked_index(&the_index, &state.lock_file, COMMIT_LOCK))\n-\t\t\tdie(_(\"Unable to write new index file\"));\n-\t}\n-\n-\treturn !!errs;\n+\treturn apply_all_patches(&state, argc, argv, options);\n }\n-- \n2.8.0.rc1.49.gca61272\n"},{"id":"280476","messageId":"xmqqbn6nikn7.fsf@gitster.mtv.corp.google.com","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"Re: [RFC/PATCH 00/48] Libifying git apply","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-03-09T18:14:20Z","receivedAt":"2016-03-09T18:14:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> One point I'd especially welcome feedback about is the fact that there\n> are many boolean options that are using OPT_BOOL(...), so they use an\n> int. And there are a few others that are using OPT_BIT(...), so they\n> use just a bit. I wonder if it is worth it to try to be consistent,\n> and maybe also to try to save some memory.\n>\n> Related to this, some of the variables for these options have not been\n> moved into the \"apply_state\" structure, because they are not global to\n> the file, but maybe for consistency they should be.\n\nThese might be worthy clean-ups but that is only if they are done\nafter we make sure conversion proper is done faithfully to the\noriginal, i.e. without introducing unnecessary bugs.  I'd advise\nagainst doing them before the libification is done.\n"},{"id":"280512","messageId":"CAGZ79kbKCZGrBw8OOJzMES0BpMm1V8KQ6Xh2oS5ARB9KNMo+dA@mail.gmail.com","threadId":"41649","inReplyTo":"1457545756-20616-5-git-send-email-chriscool@tuxfamily.org","subject":"Re: [RFC/PATCH 04/48] builtin/apply: extract line_by_line_fuzzy_match() from match_fragment()","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-03-09T22:55:19Z","receivedAt":"2016-03-09T22:55:19Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Mar 9, 2016 at 9:48 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n\nSome words in the commit message would be nice here as this is one of\nthe patches,\nwhich isn't \"obviously\" a good thing to to. This comment also applies\nto \"builtin/apply:\nintroduce 'struct apply_state' to start libifying\" where you lay out\nthe plan for the next\n~40 patches.\n\nI have only skimmed quickly over the other patches.\n\n\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/apply.c | 125 ++++++++++++++++++++++++++++++++------------------------\n>  1 file changed, 71 insertions(+), 54 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index c99c859..7d7a8ab 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -2244,6 +2244,74 @@ static void update_pre_post_images(struct image *preimage,\n>         postimage->nr -= reduced;\n>  }\n>\n> +static int line_by_line_fuzzy_match(struct image *img,\n> +                                   struct image *preimage,\n> +                                   struct image *postimage,\n> +                                   unsigned long try,\n> +                                   int try_lno,\n> +                                   int preimage_limit)\n> +{\n> +       int i;\n> +       size_t imgoff = 0;\n> +       size_t preoff = 0;\n> +       size_t postlen = postimage->len;\n> +       size_t extra_chars;\n> +       char *buf;\n> +       char *preimage_eof;\n> +       char *preimage_end;\n> +       struct strbuf fixed;\n> +       char *fixed_buf;\n> +       size_t fixed_len;\n> +\n> +       for (i = 0; i < preimage_limit; i++) {\n> +               size_t prelen = preimage->line[i].len;\n> +               size_t imglen = img->line[try_lno+i].len;\n> +\n> +               if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,\n> +                                     preimage->buf + preoff, prelen))\n> +                       return 0;\n> +               if (preimage->line[i].flag & LINE_COMMON)\n> +                       postlen += imglen - prelen;\n> +               imgoff += imglen;\n> +               preoff += prelen;\n> +       }\n> +\n> +       /*\n> +        * Ok, the preimage matches with whitespace fuzz.\n> +        *\n> +        * imgoff now holds the true length of the target that\n> +        * matches the preimage before the end of the file.\n> +        *\n> +        * Count the number of characters in the preimage that fall\n> +        * beyond the end of the file and make sure that all of them\n> +        * are whitespace characters. (This can only happen if\n> +        * we are removing blank lines at the end of the file.)\n> +        */\n> +       buf = preimage_eof = preimage->buf + preoff;\n> +       for ( ; i < preimage->nr; i++)\n> +               preoff += preimage->line[i].len;\n> +       preimage_end = preimage->buf + preoff;\n> +       for ( ; buf < preimage_end; buf++)\n> +               if (!isspace(*buf))\n> +                       return 0;\n> +\n> +       /*\n> +        * Update the preimage and the common postimage context\n> +        * lines to use the same whitespace as the target.\n> +        * If whitespace is missing in the target (i.e.\n> +        * if the preimage extends beyond the end of the file),\n> +        * use the whitespace from the preimage.\n> +        */\n> +       extra_chars = preimage_end - preimage_eof;\n> +       strbuf_init(&fixed, imgoff + extra_chars);\n> +       strbuf_add(&fixed, img->buf + try, imgoff);\n> +       strbuf_add(&fixed, preimage_eof, extra_chars);\n> +       fixed_buf = strbuf_detach(&fixed, &fixed_len);\n> +       update_pre_post_images(preimage, postimage,\n> +                              fixed_buf, fixed_len, postlen);\n> +       return 1;\n> +}\n> +\n>  static int match_fragment(struct image *img,\n>                           struct image *preimage,\n>                           struct image *postimage,\n> @@ -2253,7 +2321,7 @@ static int match_fragment(struct image *img,\n>                           int match_beginning, int match_end)\n>  {\n>         int i;\n> -       char *fixed_buf, *buf, *orig, *target;\n> +       char *fixed_buf, *orig, *target;\n>         struct strbuf fixed;\n>         size_t fixed_len, postlen;\n>         int preimage_limit;\n> @@ -2314,6 +2382,7 @@ static int match_fragment(struct image *img,\n>                  * There must be one non-blank context line that match\n>                  * a line before the end of img.\n>                  */\n> +               char *buf;\n>                 char *buf_end;\n>\n>                 buf = preimage->buf;\n> @@ -2334,59 +2403,7 @@ static int match_fragment(struct image *img,\n>          * we need it to adjust whitespace if we match.\n>          */\n>         if (ws_ignore_action == ignore_ws_change) {\n> -               size_t imgoff = 0;\n> -               size_t preoff = 0;\n> -               size_t postlen = postimage->len;\n> -               size_t extra_chars;\n> -               char *preimage_eof;\n> -               char *preimage_end;\n> -               for (i = 0; i < preimage_limit; i++) {\n> -                       size_t prelen = preimage->line[i].len;\n> -                       size_t imglen = img->line[try_lno+i].len;\n> -\n> -                       if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,\n> -                                             preimage->buf + preoff, prelen))\n> -                               return 0;\n> -                       if (preimage->line[i].flag & LINE_COMMON)\n> -                               postlen += imglen - prelen;\n> -                       imgoff += imglen;\n> -                       preoff += prelen;\n> -               }\n> -\n> -               /*\n> -                * Ok, the preimage matches with whitespace fuzz.\n> -                *\n> -                * imgoff now holds the true length of the target that\n> -                * matches the preimage before the end of the file.\n> -                *\n> -                * Count the number of characters in the preimage that fall\n> -                * beyond the end of the file and make sure that all of them\n> -                * are whitespace characters. (This can only happen if\n> -                * we are removing blank lines at the end of the file.)\n> -                */\n> -               buf = preimage_eof = preimage->buf + preoff;\n> -               for ( ; i < preimage->nr; i++)\n> -                       preoff += preimage->line[i].len;\n> -               preimage_end = preimage->buf + preoff;\n> -               for ( ; buf < preimage_end; buf++)\n> -                       if (!isspace(*buf))\n> -                               return 0;\n> -\n> -               /*\n> -                * Update the preimage and the common postimage context\n> -                * lines to use the same whitespace as the target.\n> -                * If whitespace is missing in the target (i.e.\n> -                * if the preimage extends beyond the end of the file),\n> -                * use the whitespace from the preimage.\n> -                */\n> -               extra_chars = preimage_end - preimage_eof;\n> -               strbuf_init(&fixed, imgoff + extra_chars);\n> -               strbuf_add(&fixed, img->buf + try, imgoff);\n> -               strbuf_add(&fixed, preimage_eof, extra_chars);\n> -               fixed_buf = strbuf_detach(&fixed, &fixed_len);\n> -               update_pre_post_images(preimage, postimage,\n> -                               fixed_buf, fixed_len, postlen);\n> -               return 1;\n> +               return line_by_line_fuzzy_match(img, preimage, postimage, try, try_lno, preimage_limit);\n>         }\n>\n>         if (ws_error_action != correct_ws_error)\n> --\n> 2.8.0.rc1.49.gca61272\n>\n"},{"id":"280517","messageId":"xmqqlh5rfd0t.fsf@gitster.mtv.corp.google.com","threadId":"41649","inReplyTo":"1457545756-20616-2-git-send-email-chriscool@tuxfamily.org","subject":"Re: [RFC/PATCH 01/48] builtin/apply: avoid parameter shadowing 'p_value' global","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-03-09T23:27:14Z","receivedAt":"2016-03-09T23:27:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/apply.c | 24 ++++++++++++------------\n>  1 file changed, 12 insertions(+), 12 deletions(-)\n\nTo be honest, I have to say that I do not like this change from\nreadability's point of view.  Once the global p_value becomes a\nfield in a \"apply state\" structure, functions will get a pointer to\nthe struct as a parameter, reference to it would be spelled as\n\"astate->p_value\", while a local variable or a parameter would be\n\"p_value\" and there is no shadowing issue.\n\nAlso, you wouldn't be able to catch a misconversion in this patch\nonly from the patch text, if the conversion is done this way, would\nyou?  The patch may change the parameter p_value to p_v, and change\ntwo references to p_value also to p_v, but it may leave another\nreference to p_value that originally referred to the parameter\nas-is, making it refer to the global, which would be a new bug\nintroduced by this conversion patch, but that remaining reference\nwould not show up in the patch.\n"},{"id":"280526","messageId":"CACsJy8Boz1XLv7yh5GsOQnQh1HF7RYoZ4rpQWWFc3PoTu=9m5w@mail.gmail.com","threadId":"41649","inReplyTo":"xmqqlh5rfd0t.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC/PATCH 01/48] builtin/apply: avoid parameter shadowing 'p_value' global","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-03-10T00:54:47Z","receivedAt":"2016-03-10T00:54:47Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Mar 10, 2016 at 6:27 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>> ---\n>>  builtin/apply.c | 24 ++++++++++++------------\n>>  1 file changed, 12 insertions(+), 12 deletions(-)\n>\n> To be honest, I have to say that I do not like this change from\n> readability's point of view.  Once the global p_value becomes a\n> field in a \"apply state\" structure, functions will get a pointer to\n> the struct as a parameter, reference to it would be spelled as\n> \"astate->p_value\", while a local variable or a parameter would be\n> \"p_value\" and there is no shadowing issue.\n\nWe could revert these local var rename patches at the end of the\nconversion, I think.\n\n> Also, you wouldn't be able to catch a misconversion in this patch\n> only from the patch text, if the conversion is done this way, would\n> you?  The patch may change the parameter p_value to p_v, and change\n> two references to p_value also to p_v, but it may leave another\n> reference to p_value that originally referred to the parameter\n> as-is, making it refer to the global, which would be a new bug\n> introduced by this conversion patch, but that remaining reference\n> would not show up in the patch.\n\nYeah, I wish we have a semantic parser that can help with this sort of\nrefactoring (can sparse do that?). Once we get AST tree, it should be\neasy to identify variable scope. Without it, maybe we can still rely\non the compiler by renaming _both_ global and local vars to something\nelse. That forces us (both patch writer and reviewers) to catch and\nexamine every reference.\n-- \nDuy\n"},{"id":"280534","messageId":"CAP8UFD2G-vXLhChKxmfNZsuj5yLWTD6foCHQzUWt-B04-huTZw@mail.gmail.com","threadId":"41649","inReplyTo":"CAGZ79kbKCZGrBw8OOJzMES0BpMm1V8KQ6Xh2oS5ARB9KNMo+dA@mail.gmail.com","subject":"Re: [RFC/PATCH 04/48] builtin/apply: extract line_by_line_fuzzy_match() from match_fragment()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-10T08:36:15Z","receivedAt":"2016-03-10T08:36:15Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, Mar 9, 2016 at 11:55 PM, Stefan Beller <sbeller@google.com> wrote:\n> On Wed, Mar 9, 2016 at 9:48 AM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>\n> Some words in the commit message would be nice here as this is one of\n> the patches,\n> which isn't \"obviously\" a good thing to to. This comment also applies\n> to \"builtin/apply:\n> introduce 'struct apply_state' to start libifying\" where you lay out\n> the plan for the next\n> ~40 patches.\n\nOk, I will try to explain better at least those 2 patches.\n\nThanks,\nChristian.\n"},{"id":"280538","messageId":"CACsJy8Bn1+zbALH347SNgGqSLR0ixCL0acW+DuUZH1g2HRS0ZA@mail.gmail.com","threadId":"41649","inReplyTo":"1457545756-20616-1-git-send-email-chriscool@tuxfamily.org","subject":"Re: [RFC/PATCH 00/48] Libifying git apply","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-03-10T09:26:40Z","receivedAt":"2016-03-10T09:26:40Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Mar 10, 2016 at 12:48 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> This is a patch series about libifying \"git apply\" functionality, to\n> be able to use this functionality in \"git am\" without spawning new\n> processes. This should make \"git am\" and \"git rebase\" significantly\n> faster.\n>\n> This has been discussed in the following thread:\n>\n> http://thread.gmane.org/gmane.comp.version-control.git/287236/\n>\n> This RFC patch series for now just gets rid of the global variables\n> and refactors the code around a bit.\n>\n> As suggested by Junio the global variables in builtin/apply.c are just\n> thrown into a single \"apply_state\" structure that is passed around the\n> callchain. A new parameter called \"state\" that is a pointer to the\n> \"apply_state\" structure comes at the beginning of the helper functions\n> that need it.\n>\n> Before I make further changes to handle erroneous input and make the\n> libified functions not die() and properly clean things up, I'd be\n> happy to get some feedback.\n\nI didn't review individual patches. Instead I redid the whole thing\n(in a slightly different way) and compared my end result to yours. In\ngeneral it looks good but..\n\n1) I think you should focus the series on moving global vars to struct\napply_state only. You can save code move patches for the later phase.\nEasier to review.\n\n2) Given that there are only four local variables shadowing global\nones, p_value, linenr and options, I think it's ok to drop 1/48 and\n2/48 and keep the good old names. You just need to mention about them\nand what function they are declared in in the relevant \"move global\n...\" patch so the reviewer is aware of it.\n\n3) Moving lock_file to struct apply_state, then putting the whole\nstruct on stack, could be problematic. I believe there's a global\nlinked list keeping references of all lock_file variables until the\nend of time, so we can't destroy lock_file/apply_state until we are\ncertain it's safe to do so. We could simply leave lock_file as a\nglobal var for now (with a note in struct apply_state so we don't\nforget). We can always do fancy stuff like malloc() later on if we\nneed to.\n\n4) I noticed on the interdiff that there are translatable strings in\nthis file but not marked as such. You're going to spend lots of time\nreading this file and are in a very good positioin to determine if a\nstring should be translated (i.e. wrap _() around it) or not. So maybe\nyou can have a look at this in the next series too. It's absolutely ok\nif you say \"no\" here.\n\n5) Minor detail, but we can rename prefix_ to prefix in\ninit_apply_state(). There trailing underscore was there in cmd_apply\nbecause there's the global \"prefix\", but it's gone now.\n\nLooking forward to seeing you double, triple git-rebase's speed.\n-- \nDuy\n"},{"id":"280543","messageId":"CAP8UFD0UYsaz6ZatZCXuxmCc-ge_Tu3mL16Bz25EUFGf9ma1Ow@mail.gmail.com","threadId":"41649","inReplyTo":"CACsJy8Boz1XLv7yh5GsOQnQh1HF7RYoZ4rpQWWFc3PoTu=9m5w@mail.gmail.com","subject":"Re: [RFC/PATCH 01/48] builtin/apply: avoid parameter shadowing 'p_value' global","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-10T10:45:01Z","receivedAt":"2016-03-10T10:45:01Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, Mar 10, 2016 at 1:54 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Thu, Mar 10, 2016 at 6:27 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Christian Couder <christian.couder@gmail.com> writes:\n>>\n>>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>>> ---\n>>>  builtin/apply.c | 24 ++++++++++++------------\n>>>  1 file changed, 12 insertions(+), 12 deletions(-)\n>>\n>> To be honest, I have to say that I do not like this change from\n>> readability's point of view.  Once the global p_value becomes a\n>> field in a \"apply state\" structure, functions will get a pointer to\n>> the struct as a parameter, reference to it would be spelled as\n>> \"astate->p_value\", while a local variable or a parameter would be\n>> \"p_value\" and there is no shadowing issue.\n>\n> We could revert these local var rename patches at the end of the\n> conversion, I think.\n>\n>> Also, you wouldn't be able to catch a misconversion in this patch\n>> only from the patch text, if the conversion is done this way, would\n>> you?  The patch may change the parameter p_value to p_v, and change\n>> two references to p_value also to p_v, but it may leave another\n>> reference to p_value that originally referred to the parameter\n>> as-is, making it refer to the global, which would be a new bug\n>> introduced by this conversion patch, but that remaining reference\n>> would not show up in the patch.\n>\n> Yeah, I wish we have a semantic parser that can help with this sort of\n> refactoring (can sparse do that?). Once we get AST tree, it should be\n> easy to identify variable scope. Without it, maybe we can still rely\n> on the compiler by renaming _both_ global and local vars to something\n> else. That forces us (both patch writer and reviewers) to catch and\n> examine every reference.\n\nI agree that the change in the patch is not very nice.\nI can do one of the following:\n\n1) do as Junio suggests, just discard this change and wait until\np_value is moved into apply_state for the problem to be solved; a\nsmall downside of this is that if you compile with -Wshadow after each\nchange you will get some warnings until p_value is moved into\napply_state; I could move the patch to move p_value at the beginning\nof the series but it is a bit involved and easier to review if it is\ndone towards the end,\n\n2) revert these local var rename patches at the end of the conversion,\nas Duy suggests\n\n3) instead of renaming the local \"p_value\" variable, rename the global\n\"p_value\" to maybe \"state_p_value\", so that when I move it into\napply_state I just need to s/state_p_value/state->p_value/.\n\nI'd rather do 3) than 1) or 2) but I am also ok with 1) and 2).\n\nThanks,\nChristian.\n"},{"id":"280621","messageId":"CAP8UFD2nPe8MqESWm5Yug4dqdCp5QqyM9R0u1zwL29BkpdbToQ@mail.gmail.com","threadId":"41649","inReplyTo":"xmqqbn6nikn7.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC/PATCH 00/48] Libifying git apply","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-11T15:57:35Z","receivedAt":"2016-03-11T15:57:35Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, Mar 9, 2016 at 7:14 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> One point I'd especially welcome feedback about is the fact that there\n>> are many boolean options that are using OPT_BOOL(...), so they use an\n>> int. And there are a few others that are using OPT_BIT(...), so they\n>> use just a bit. I wonder if it is worth it to try to be consistent,\n>> and maybe also to try to save some memory.\n>>\n>> Related to this, some of the variables for these options have not been\n>> moved into the \"apply_state\" structure, because they are not global to\n>> the file, but maybe for consistency they should be.\n>\n> These might be worthy clean-ups but that is only if they are done\n> after we make sure conversion proper is done faithfully to the\n> original, i.e. without introducing unnecessary bugs.  I'd advise\n> against doing them before the libification is done.\n\nOk, I will try to avoid those kind of clean-ups.\n"},{"id":"280624","messageId":"CAP8UFD0MEPpfpCHxkX-EKHb2F+xmObqZa4w1Ub=NQ=7W7OVLYw@mail.gmail.com","threadId":"41649","inReplyTo":"CACsJy8Bn1+zbALH347SNgGqSLR0ixCL0acW+DuUZH1g2HRS0ZA@mail.gmail.com","subject":"Re: [RFC/PATCH 00/48] Libifying git apply","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-11T17:34:50Z","receivedAt":"2016-03-11T17:34:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, Mar 10, 2016 at 10:26 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Thu, Mar 10, 2016 at 12:48 AM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>> This is a patch series about libifying \"git apply\" functionality, to\n>> be able to use this functionality in \"git am\" without spawning new\n>> processes. This should make \"git am\" and \"git rebase\" significantly\n>> faster.\n>>\n>> This has been discussed in the following thread:\n>>\n>> http://thread.gmane.org/gmane.comp.version-control.git/287236/\n>>\n>> This RFC patch series for now just gets rid of the global variables\n>> and refactors the code around a bit.\n>>\n>> As suggested by Junio the global variables in builtin/apply.c are just\n>> thrown into a single \"apply_state\" structure that is passed around the\n>> callchain. A new parameter called \"state\" that is a pointer to the\n>> \"apply_state\" structure comes at the beginning of the helper functions\n>> that need it.\n>>\n>> Before I make further changes to handle erroneous input and make the\n>> libified functions not die() and properly clean things up, I'd be\n>> happy to get some feedback.\n>\n> I didn't review individual patches. Instead I redid the whole thing\n> (in a slightly different way) and compared my end result to yours. In\n> general it looks good but..\n>\n> 1) I think you should focus the series on moving global vars to struct\n> apply_state only. You can save code move patches for the later phase.\n> Easier to review.\n\nI am not sure what you mean by \"the later phase\", but I tend to agree\nand that's mostly what I did.\nMost of the code move are at the end of the series so after the global\nvariable related changes.\nThere are a few exceptions because in a few cases it was difficult to\nunderstand the code without a refactoring.\nIn such cases I think the refactoring can also actually help the reviewer.\n\n> 2) Given that there are only four local variables shadowing global\n> ones, p_value, linenr and options, I think it's ok to drop 1/48 and\n> 2/48 and keep the good old names. You just need to mention about them\n> and what function they are declared in in the relevant \"move global\n> ...\" patch so the reviewer is aware of it.\n\nAbout 1/48 (builtin/apply: avoid parameter shadowing 'p_value') this\nis discussed in its own thread.\nIn 2/48 (builtin/apply: avoid parameter shadowing 'linenr'), I change\nthe \"good old name\" only twice in a small function, and I don't think\nkeeping the old name is a big deal there.\n\n> 3) Moving lock_file to struct apply_state, then putting the whole\n> struct on stack, could be problematic. I believe there's a global\n> linked list keeping references of all lock_file variables until the\n> end of time, so we can't destroy lock_file/apply_state until we are\n> certain it's safe to do so. We could simply leave lock_file as a\n> global var for now (with a note in struct apply_state so we don't\n> forget). We can always do fancy stuff like malloc() later on if we\n> need to.\n\nThanks for this information. Though I prefer to do the fancy stuff\nright away, that is something like:\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 4f57bce..6029869 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -52,6 +52,12 @@ struct apply_state {\n        const char *prefix;\n        int prefix_length;\n\n+       /*\n+        * Since lockfile.c keeps a linked list of all created\n+        * lock_file structures, it isn't safe to free(lock_file).\n+        */\n+       struct lock_file *lock_file;\n+\n        int apply;\n        int allow_overlap;\n        int apply_in_reverse;\n@@ -4517,8 +4523,6 @@ static int write_out_results(struct apply_state\n*state, struct patch *list)\n        return errs;\n }\n\n-static struct lock_file lock_file;\n-\n #define INACCURATE_EOF (1<<0)\n #define RECOUNT                (1<<1)\n\n@@ -4566,8 +4570,10 @@ static int apply_patch(struct apply_state *state,\n                state->apply = 0;\n\n        state->update_index = state->check_index && state->apply;\n-       if (state->update_index && newfd < 0)\n-               newfd = hold_locked_index(&lock_file, 1);\n+       if (state->update_index && newfd < 0) {\n+               state->lock_file = xcalloc(1, sizeof(struct lock_file));\n+               newfd = hold_locked_index(state->lock_file, 1);\n+       }\n\n        if (state->check_index) {\n                if (read_cache() < 0)\n@@ -4780,7 +4786,7 @@ static int apply_all_patches(struct apply_state *state,\n        }\n\n        if (state->update_index) {\n-               if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n+               if (write_locked_index(&the_index, state->lock_file,\nCOMMIT_LOCK))\n                        die(_(\"Unable to write new index file\"));\n        }\n\nIt makes it possible to remove the 'newfd' variable as it is only used\nto check if hold_locked_index() has already been called and now\n\"state->lock_file == NULL\" can be used to do that.\n\nBy the way I wonder if I should also change \"static struct lock_file\nlock\" in build_fake_ancestor().\n\n> 4) I noticed on the interdiff that there are translatable strings in\n> this file but not marked as such. You're going to spend lots of time\n> reading this file and are in a very good positioin to determine if a\n> string should be translated (i.e. wrap _() around it) or not. So maybe\n> you can have a look at this in the next series too. It's absolutely ok\n> if you say \"no\" here.\n\nI will see if I can do that towards the end of the series, but this is\nnot at all on my radar for now.\n\n> 5) Minor detail, but we can rename prefix_ to prefix in\n> init_apply_state(). There trailing underscore was there in cmd_apply\n> because there's the global \"prefix\", but it's gone now.\n\nYeah, I think this is worth doing, so it is done in my current series:\n\nhttps://github.com/chriscool/git/commits/libify-apply21\n\n> Looking forward to seeing you double, triple git-rebase's speed.\n\nThanks for your reviews and comments,\nChristian.\n"}]}