{"thread":{"id":"42281","subject":"[PATCH v2 01/94] builtin/apply: make gitdiff_verify_name() return void","startedAt":"2016-05-11T13:16:11Z","lastAt":"2016-06-16T02:19:52Z","messageCount":148,"participants":["Christian Couder","Johannes Sixt","Junio C Hamano","Johannes Schindelin","Eric Sunshine"],"isPatch":true,"patchVersion":2,"patchTotal":94},"messages":[{"id":"286170","messageId":"20160511131745.2914-1-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":null,"subject":"[PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:11Z","receivedAt":"2016-05-11T13:16:11Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Goal\n~~~~\n\nThis is a patch series about libifying `git apply` functionality, and\nusing this libified functionality in `git am`, so that no 'git apply'\nprocess is spawn anymore. This makes `git am` significantly faster, so\n`git rebase`, when it uses the am backend, is also significantly\nfaster.\n\nPrevious discussions and patches series\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis has initially been discussed in the following thread:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/287236/\n\nThen a RFC patch series was sent:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/288489/\n\nThen v1 was sent:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/292324/\n\nHighlevel view of the pqtches in the series\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis new patch series is built on top of the above previous work.\n\n  - Patches 1/94 to 47/94 are here from the RFC patch series.\n\nThey get rid of most of the global variables in builtin/apply.c by\nmoving the variables into a new 'struct apply_state', and they\nrefactor the code around a bit.\n\nThey haven't changed much since v1. There are mostly variables that\nhave been moved around inside 'struct apply_state' or inside\nmatch_fragment(), new lines that have removed in 'struct apply_state'\nand function parameters that have been renamed.\n\n  - Patches 48/94 to 84/94 were new in v1.\n\nThey finish libifying the apply functionality that was in\nbuiltin/apply.c and move it into apply.{c,h}. And they use this\nlibified functionality in git am so that it doesn't launch git apply\nprocesses any more.\n\nThere are many changes in these patches, as there were a lot of great\nsuggestions from many reviewers to improve on v1:\n\n      - Lockfile management changes as suggested by Junio.\n      - Many memory leaks were fixed as suggested by Eric.\n      - A patch was splitted into two as suggested by Duy.\n      - Some file descriptors have been closed as suggested by Dscho.\n      - Some early return were moved up as suggested by Eric.\n      - Many commit messages were improved.\n\nI am not very happy that I added some gotos, but it looked like a not\ntoo bad way to make sure that the memory and file descriptor cleanups\nwere done before returning from some functions.\n\n  - Patches 85/94 to 94/94 are new and can be considered RFC.\n\nThey implement a way to make the libified apply silent. It is a new\nfeature in the libified apply functionality.\n\nI consider that the apply functionality is properly libified before\nthese patches, and that they should be in a separate series, but\nunfortunately using the libified apply in \"git am\" unmasks the fact\nthat \"git am\", since it was a shell script, has been silencing the\napply functionality by \"futzing with file descriptors\". And\nunfortunately this makes some reviewers unhappy.\n\nThe last patch 94/94 adds a --silent command line option to git apply.\nThis is not necessary, but some scripts could perhaps use it, and it\ncould make it easier to test the new silent feature.\n\nBy the way there are no tests yet for this new feature, and I am not\nsure at all that \"--silent\" and \"be_silent\" are good names. Also I\nwill perhaps be asked to move or merge this part of this series, to\nremove the \"futzing with file descriptors\" earlier in the former\npatches. That's why this part of the series can be considered RFC.\n\nGeneral comments\n~~~~~~~~~~~~~~~~\n\nSorry if this patch series is long. I can split it into two or more\nseries if it is prefered.\n\nI can also send diffs between this version and the previous one, but\nfor now I'd rather not send them in this email, as it would make it\nvery long.\n\nThe benefits are not just related to not creating new processes. When\n`git am` launched a `git apply` process, this new process had to read\nthe index from disk. Then after the `git apply`process had terminated,\n`git am` dropped its index and read the index from disk to get the\nindex that had been modified by the `git apply`process. This was\ninefficient and also prevented the split-index mechanism to provide\nmany performance benefits.\n\nUsing this series as rebase material, Duy explains it like this:\n\n > Without the series, the picture is not so surprising. We run git-apply\n > 80+ times, each consists of this sequence\n >\n > read index\n > write index (cache tree updates only)\n > read index again\n > optionally initialize name hash (when new entries are added, I guess)\n > read packed-refs\n > write index\n >\n > With this series, we run a single git-apply which does\n >\n > read index (and sharedindex too if in split-index mode)\n > initialize name hash\n > write index 80+ times\n\n(See: http://thread.gmane.org/gmane.comp.version-control.git/292324/focus=292460)\n\nLinks\n~~~~~\n\nThis patch series is available here:\n\nhttps://github.com/chriscool/git/commits/libify-apply-use-in-am54\n\nThe previous version, v1, is available here:\n\nhttps://github.com/chriscool/git/commits/libify-apply-use-in-am25 \n\nPerformance numbers\n~~~~~~~~~~~~~~~~~~~\n\nOnly tests on Linux have been performed. It could be interesting to\ntest on other platforms especially Windows and perhaps OSX too.\n\n  - Around mid April Ævar did a huge many-hundred commit rebase on the\n    kernel with untracked cache.\n\ncommand: git rebase --onto 1993b17 52bef0c 29dde7c\n\nVanilla \"next\" without split index:                1m54.953s\nVanilla \"next\" with split index:                   1m22.476s\nThis series on top of \"next\" without split index:  1m12.034s\nThis series on top of \"next\" with split index:     0m15.678s\n\nÆvar used his Debian laptop with SSD.\n\n  - Around mid April I tested rebasing 13 commits in Booking.com's\n    monorepo on a Red Hat 6.5 server with split-index and\n    GIT_TRACE_PERFORMANCE=1.\n\nWith Git v2.8.0, the rebase took 6.375888383 s, with the git am\ncommand launched by the rebase command taking 3.705677431 s.\n\nWith this series on top of next, the rebase took 3.044529494 s, with\nthe git am command launched by the rebase command taking 0.583521168\ns.\n\n\nChristian Couder (94):\n  builtin/apply: make gitdiff_verify_name() return void\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: move 'read_stdin' global into cmd_apply()\n  builtin/apply: introduce 'struct apply_state' to start libifying\n  builtin/apply: move 'state' init into init_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 '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 'state_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' check into check_apply_state()\n  builtin/apply: move applying patches into apply_all_patches()\n  builtin/apply: rename 'prefix_' parameter to 'prefix'\n  builtin/apply: move 'lock_file' global into 'struct apply_state'\n  builtin/apply: move 'newfd' global into 'struct apply_state'\n  builtin/apply: make apply_patch() return -1 instead of die()ing\n  builtin/apply: read_patch_file() return -1 instead of die()ing\n  builtin/apply: make find_header() return -1 instead of die()ing\n  builtin/apply: make parse_chunk() return a negative integer on error\n  builtin/apply: make parse_single_patch() return -1 on error\n  apply: move 'struct apply_state' to apply.h\n  builtin/apply: make parse_whitespace_option() return -1 instead of\n    die()ing\n  builtin/apply: make parse_ignorewhitespace_option() return -1 instead\n    of die()ing\n  builtin/apply: move init_apply_state() to apply.c\n  apply: make init_apply_state() return -1 instead of exit()ing\n  builtin/apply: make check_apply_state() return -1 instead of die()ing\n  builtin/apply: move check_apply_state() to apply.c\n  builtin/apply: make apply_all_patches() return -1 on error\n  builtin/apply: make parse_traditional_patch() return -1 on error\n  builtin/apply: make gitdiff_*() return 1 at end of header\n  builtin/apply: make gitdiff_*() return -1 on error\n  builtin/apply: change die_on_unsafe_path() to check_unsafe_path()\n  builtin/apply: make build_fake_ancestor() return -1 on error\n  builtin/apply: make remove_file() return -1 on error\n  builtin/apply: make add_conflicted_stages_file() return -1 on error\n  builtin/apply: make add_index_file() return -1 on error\n  builtin/apply: make create_file() return -1 on error\n  builtin/apply: make write_out_one_result() return -1 on error\n  builtin/apply: make write_out_results() return -1 on error\n  builtin/apply: make try_create_file() return -1 on error\n  builtin/apply: make create_one_file() return -1 on error\n  builtin/apply: rename option parsing functions\n  apply: rename and move opt constants to apply.h\n  Move libified code from builtin/apply.c to apply.{c,h}\n  apply: make some parsing functions static again\n  run-command: make dup_devnull() non static\n  apply: roll back index lock file in case of error\n  environment: add set_index_file()\n  builtin/am: use apply api in run_apply()\n  write_or_die: use warning() instead of fprintf(stderr, ...)\n  apply: add 'be_silent' variable to 'struct apply_state'\n  apply: make 'be_silent' incomatible with 'apply_verbosely'\n  apply: don't print on stdout when be_silent is set\n  usage: add set_warn_routine()\n  usage: add get_error_routine() and get_warn_routine()\n  apply: change error_routine when be_silent is set\n  am: use be_silent in 'struct apply_state' to shut up applying patches\n  run-command: make dup_devnull() static again\n  builtin/apply: add a cli option for be_silent\n\n Makefile                   |    1 +\n builtin/apply.c => apply.c | 1750 ++++++++--------\n apply.h                    |  146 ++\n builtin/am.c               |   91 +-\n builtin/apply.c            | 4762 +-------------------------------------------\n cache.h                    |    1 +\n environment.c              |   10 +\n git-compat-util.h          |    3 +\n run-command.c              |    2 +-\n t/t4012-diff-binary.sh     |    4 +-\n t/t4254-am-corrupt.sh      |    2 +-\n usage.c                    |   15 +\n write_or_die.c             |    6 +-\n 13 files changed, 1324 insertions(+), 5469 deletions(-)\n copy builtin/apply.c => apply.c (73%)\n create mode 100644 apply.h\n rewrite builtin/apply.c (98%)\n\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286169","messageId":"20160511131745.2914-2-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 01/94] builtin/apply: make gitdiff_verify_name() return void","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:12Z","receivedAt":"2016-05-11T13:16:12Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"As the value returned by gitdiff_verify_name() is put into the\nsame variable that is passed as a parameter to this function,\nit is simpler to pass the address of the variable and have\ngitdiff_verify_name() change the variable itself.\n\nThis also makes it possible to later have this function return\n-1 instead of die()ing in case of error.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 26 +++++++++++++-------------\n 1 file changed, 13 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 8e4da2e..fe5aebd 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -925,43 +925,43 @@ 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 void gitdiff_verify_name(const char *line, int isnull, char **name, int side)\n {\n-\tif (!orig_name && !isnull)\n-\t\treturn find_name(line, NULL, p_value, TERM_TAB);\n+\tif (!*name && !isnull) {\n+\t\t*name = find_name(line, NULL, p_value, TERM_TAB);\n+\t\treturn;\n+\t}\n \n-\tif (orig_name) {\n-\t\tint len = strlen(orig_name);\n+\tif (*name) {\n+\t\tint len = strlen(*name);\n \t\tchar *another;\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n-\t\t\t    orig_name, linenr);\n+\t\t\t    *name, linenr);\n \t\tanother = find_name(line, NULL, p_value, TERM_TAB);\n-\t\tif (!another || memcmp(another, orig_name, len + 1))\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\tfree(another);\n-\t\treturn orig_name;\n \t} else {\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\treturn NULL;\n \t}\n }\n \n static int gitdiff_oldname(const char *line, struct patch *patch)\n {\n-\tpatch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name,\n-\t\t\t\t\t      DIFF_OLD_NAME);\n+\tgitdiff_verify_name(line, patch->is_new, &patch->old_name,\n+\t\t\t    DIFF_OLD_NAME);\n \treturn 0;\n }\n \n static int gitdiff_newname(const char *line, struct patch *patch)\n {\n-\tpatch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name,\n-\t\t\t\t\t      DIFF_NEW_NAME);\n+\tgitdiff_verify_name(line, patch->is_delete, &patch->new_name,\n+\t\t\t    DIFF_NEW_NAME);\n \treturn 0;\n }\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286172","messageId":"20160511131745.2914-3-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 02/94] builtin/apply: avoid parameter shadowing 'p_value' global","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:13Z","receivedAt":"2016-05-11T13:16:13Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Let's just rename the global 'state_p_value' as it will become\n'state->p_value' in a following patch.\n\nThis also avoid errors when compiling with -Wshadow and makes\nit safer to later move global variables into a \"state\" struct.\n\nHelped-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 34 +++++++++++++++++-----------------\n 1 file changed, 17 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex fe5aebd..e133b38 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -35,7 +35,7 @@ static int prefix_length = -1;\n static int newfd = -1;\n \n static int unidiff_zero;\n-static int p_value = 1;\n+static int state_p_value = 1;\n static int p_value_known;\n static int check_index;\n static int update_index;\n@@ -872,24 +872,24 @@ static void parse_traditional_patch(const char *first, const char *second, struc\n \t\tq = guess_p_value(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@@ -928,7 +928,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)\n static void gitdiff_verify_name(const char *line, int isnull, char **name, int side)\n {\n \tif (!*name && !isnull) {\n-\t\t*name = find_name(line, NULL, p_value, TERM_TAB);\n+\t\t*name = find_name(line, NULL, state_p_value, TERM_TAB);\n \t\treturn;\n \t}\n \n@@ -938,7 +938,7 @@ static void gitdiff_verify_name(const char *line, int isnull, char **name, int s\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n \t\t\t    *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@@ -997,7 +997,7 @@ static int gitdiff_copysrc(const char *line, 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@@ -1005,7 +1005,7 @@ static int gitdiff_copydst(const char *line, 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@@ -1013,7 +1013,7 @@ static int gitdiff_renamesrc(const char *line, 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@@ -1021,7 +1021,7 @@ static int gitdiff_renamedst(const char *line, 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@@ -1092,10 +1092,10 @@ static const char *skip_tree_prefix(const char *line, int llen)\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@@ -1481,8 +1481,8 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc\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@@ -4461,7 +4461,7 @@ static int option_parse_include(const struct option *opt,\n static int option_parse_p(const struct option *opt,\n \t\t\t  const char *arg, int unset)\n {\n-\tp_value = atoi(arg);\n+\tstate_p_value = atoi(arg);\n \tp_value_known = 1;\n \treturn 0;\n }\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286171","messageId":"20160511131745.2914-4-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 03/94] builtin/apply: avoid parameter shadowing 'linenr' global","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:14Z","receivedAt":"2016-05-11T13:16:14Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Let's just rename the global 'state_linenr' as it will become\n'state->linenr' in a following patch.\n\nThis also avoid errors when compiling with -Wshadow and makes\nit safer to later move global variables into a \"state\" struct.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 48 ++++++++++++++++++++++++------------------------\n 1 file changed, 24 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex e133b38..705a9c8 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -144,7 +144,7 @@ static int max_change, max_len;\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+static int state_linenr = 1;\n \n /*\n  * This represents one \"hunk\" from a patch, starting with\n@@ -905,7 +905,7 @@ static void parse_traditional_patch(const char *first, const char *second, struc\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(const char *line, struct patch *patch)\n@@ -937,17 +937,17 @@ static void gitdiff_verify_name(const char *line, int isnull, char **name, int s\n \t\tchar *another;\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n-\t\t\t    *name, linenr);\n+\t\t\t    *name, state_linenr);\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-\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} else {\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}\n }\n \n@@ -1272,8 +1272,8 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct\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)(const char *, struct patch *);\n@@ -1440,7 +1440,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc\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@@ -1461,7 +1461,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc\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@@ -1482,13 +1482,13 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc\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@@ -1510,7 +1510,7 @@ static int find_header(const char *line, unsigned long size, int *hdrsize, struc\n \t\t/* Ok, we'll consider it a patch */\n \t\tparse_traditional_patch(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@@ -1538,7 +1538,7 @@ static void check_whitespace(const char *line, int len, 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(result, line + 1, len - 2, state_linenr);\n }\n \n /*\n@@ -1568,11 +1568,11 @@ static int parse_fragment(const char *line, unsigned long size,\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@@ -1668,10 +1668,10 @@ static int parse_single_patch(const char *line, unsigned long size, struct patch\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(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@@ -1799,13 +1799,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@@ -1859,7 +1859,7 @@ 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@@ -1892,7 +1892,7 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)\n \tforward = parse_binary_hunk(&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@@ -2010,7 +2010,7 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)\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\tstate_linenr++;\n \t\t\tused = parse_binary(buffer + hd + llen,\n \t\t\t\t\t    size - hd - llen, patch);\n \t\t\tif (used < 0)\n@@ -2031,7 +2031,7 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)\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@@ -2045,7 +2045,7 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)\n \t\t */\n \t\tif ((apply || 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-- \n2.8.2.490.g3dabe57\n"},{"id":"286173","messageId":"20160511131745.2914-5-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 04/94] builtin/apply: avoid local variable shadowing 'len' parameter","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:15Z","receivedAt":"2016-05-11T13:16:15Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This is just a cleanup to avoid errors when compiling with -Wshadow and\nto make it safer to later move global variables into a \"state\" struct.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 705a9c8..bb8bf7f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2194,17 +2194,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@@ -2223,11 +2223,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.2.490.g3dabe57\n"},{"id":"286261","messageId":"20160511131745.2914-6-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 05/94] builtin/apply: extract line_by_line_fuzzy_match() from match_fragment()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:16Z","receivedAt":"2016-05-11T13:16:16Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"The match_fragment() function is very big and contains a big special case\nalgorithm that does line by line fuzzy matching. So let's extract this\nalgorithm in a separate line_by_line_fuzzy_match() function.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 126 +++++++++++++++++++++++++++++++-------------------------\n 1 file changed, 71 insertions(+), 55 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex bb8bf7f..7bab466 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2242,6 +2242,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@@ -2331,61 +2399,9 @@ static int match_fragment(struct image *img,\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-\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}\n+\tif (ws_ignore_action == ignore_ws_change)\n+\t\treturn line_by_line_fuzzy_match(img, preimage, postimage,\n+\t\t\t\t\t\ttry, try_lno, preimage_limit);\n \n \tif (ws_error_action != correct_ws_error)\n \t\treturn 0;\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286175","messageId":"20160511131745.2914-7-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 06/94] builtin/apply: move 'options' variable into cmd_apply()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:17Z","receivedAt":"2016-05-11T13:16:17Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"The 'options' variable doesn't need to be static and global to the\nfile. It can be local to cmd_apply(), so let's move it there.\n\nThis will make it easier to libify the apply functionality.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 7bab466..5a1d65a 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@@ -4517,6 +4516,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.2.490.g3dabe57\n"},{"id":"286174","messageId":"20160511131745.2914-8-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 07/94] builtin/apply: move 'read_stdin' global into cmd_apply()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:18Z","receivedAt":"2016-05-11T13:16:18Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"The 'read_stdin' variable doesn't need to be static and global to the\nfile. It can be local to cmd_apply(), so let's move it there.\n\nThis will make it easier to libify the apply functionality.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 5a1d65a..c911e4e 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -78,7 +78,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@@ -4517,6 +4516,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 \n \tconst char *whitespace_option = NULL;\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286176","messageId":"20160511131745.2914-9-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 08/94] builtin/apply: introduce 'struct apply_state' to start libifying","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:19Z","receivedAt":"2016-05-11T13:16:19Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Currently commands that want to use the apply functionality have to launch\na \"git apply\" process which can be bad for performance.\n\nLet's start libifying the apply functionality and to do that we first need\nto get rid of the global variables in \"builtin/apply.c\".\n\nThis patch introduces \"struct apply_state\" into which all the previously\nglobal variables will be moved. A new parameter called \"state\" that is a\npointer to the \"apply_state\" structure will come at the beginning of the\nhelper functions that need it and will be passed around the call chain.\n\nTo start let's move the \"prefix\" and \"prefix_length\" global variables into\n\"struct apply_state\".\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 c911e4e..ae068e7 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@@ -748,7 +751,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@@ -761,17 +764,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@@ -858,7 +861,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@@ -866,8 +872,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\tstate_p_value = p;\n@@ -1429,7 +1435,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@@ -1506,7 +1516,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\tstate_linenr += 2;\n \t\treturn offset;\n@@ -1913,21 +1923,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@@ -1944,16 +1954,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@@ -1980,17 +1990,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@@ -4367,7 +4377,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@@ -4384,14 +4397,14 @@ 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\tfree_patch(patch);\n \t\t\tbreak;\n \t\t}\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@@ -4517,6 +4530,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\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 \n@@ -4589,15 +4603,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@@ -4628,23 +4644,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.2.490.g3dabe57\n"},{"id":"286179","messageId":"20160511131745.2914-10-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 09/94] builtin/apply: move 'state' init into init_apply_state()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:20Z","receivedAt":"2016-05-11T13:16:20Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"When the apply functionality will be libified, the 'struct apply_state'\nwill be used by different pieces of code.\n\nTo properly initialize a 'struct apply_state', let's provide a nice\nand easy to use init_apply_state() function.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 ae068e7..e133033 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4522,6 +4522,19 @@ 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+\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+\n int cmd_apply(int argc, const char **argv, const char *prefix_)\n {\n \tint i;\n@@ -4603,15 +4616,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-\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+\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.2.490.g3dabe57\n"},{"id":"286177","messageId":"20160511131745.2914-11-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 10/94] builtin/apply: move 'unidiff_zero' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:21Z","receivedAt":"2016-05-11T13:16:21Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'unidiff_zero' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 e133033..44ae95d 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -24,6 +24,8 @@\n struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n+\n+\tint unidiff_zero;\n };\n \n /*\n@@ -37,7 +39,6 @@ struct apply_state {\n  */\n static int newfd = -1;\n \n-static int unidiff_zero;\n static int state_p_value = 1;\n static int p_value_known;\n static int check_index;\n@@ -2694,7 +2695,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@@ -2836,7 +2838,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@@ -2844,7 +2846,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@@ -3067,7 +3069,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@@ -3080,7 +3082,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@@ -3388,8 +3390,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@@ -3415,7 +3420,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@@ -3459,7 +3464,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@@ -3467,9 +3473,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@@ -3717,7 +3723,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@@ -3816,13 +3822,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@@ -3832,7 +3838,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@@ -4597,7 +4603,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.2.490.g3dabe57\n"},{"id":"286257","messageId":"20160511131745.2914-12-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 11/94] builtin/apply: move 'check' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:22Z","receivedAt":"2016-05-11T13:16:22Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'check' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 44ae95d..6bf103a 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -25,12 +25,15 @@ struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\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@@ -2052,7 +2054,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\"), state_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@@ -4573,7 +4575,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@@ -4638,7 +4640,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.2.490.g3dabe57\n"},{"id":"286180","messageId":"20160511131745.2914-13-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 12/94] builtin/apply: move 'check_index' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:23Z","receivedAt":"2016-05-11T13:16:23Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'check_index' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 6bf103a..5d8f410 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -30,6 +30,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@@ -37,14 +41,12 @@ 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 static int newfd = -1;\n \n static int state_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@@ -3246,13 +3248,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@@ -3278,7 +3281,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@@ -3296,7 +3300,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@@ -3355,7 +3359,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@@ -3382,7 +3388,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@@ -3432,11 +3438,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@@ -3471,7 +3477,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@@ -3502,7 +3508,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@@ -3525,7 +3534,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@@ -3575,11 +3584,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@@ -3655,7 +3666,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@@ -3676,7 +3687,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@@ -3691,14 +3702,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@@ -3738,7 +3749,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@@ -3765,7 +3776,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@@ -3820,7 +3831,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 && newfd < 0)\n \t\tnewfd = 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@@ -4577,7 +4588,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@@ -4636,20 +4647,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.2.490.g3dabe57\n"},{"id":"286178","messageId":"20160511131745.2914-14-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 13/94] builtin/apply: move 'apply_in_reverse' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:24Z","receivedAt":"2016-05-11T13:16:24Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'apply_in_reverse' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 5d8f410..73cef9b 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 \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@@ -1560,8 +1561,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@@ -1601,12 +1605,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@@ -1614,7 +1618,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@@ -1670,7 +1674,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@@ -1682,7 +1689,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 = state_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\"), state_linenr);\n \t\tfragment->patch = line;\n@@ -2012,8 +2019,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@@ -2745,7 +2754,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@@ -2918,7 +2927,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@@ -2952,7 +2961,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@@ -2965,7 +2976,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@@ -2998,7 +3009,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@@ -3059,7 +3072,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@@ -3082,7 +3095,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@@ -4421,7 +4434,7 @@ static int apply_patch(struct apply_state *state,\n \t\t\tfree_patch(patch);\n \t\t\tbreak;\n \t\t}\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@@ -4614,7 +4627,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.2.490.g3dabe57\n"},{"id":"286256","messageId":"20160511131745.2914-15-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 14/94] builtin/apply: move 'apply_with_reject' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:25Z","receivedAt":"2016-05-11T13:16:25Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'apply_with_reject' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 73cef9b..53cc280 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -26,6 +26,7 @@ struct apply_state {\n \tint prefix_length;\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@@ -3101,7 +3101,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@@ -4631,7 +4631,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@@ -4653,7 +4653,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@@ -4662,7 +4662,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.2.490.g3dabe57\n"},{"id":"286262","messageId":"20160511131745.2914-16-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 15/94] builtin/apply: move 'apply_verbosely' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:26Z","receivedAt":"2016-05-11T13:16:26Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'apply_verbosely' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 26 +++++++++++++-------------\n 1 file changed, 13 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 53cc280..97af6ea 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -27,6 +27,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@@ -2810,7 +2810,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@@ -2925,7 +2925,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@@ -2947,7 +2947,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@@ -3861,7 +3861,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@@ -4292,7 +4292,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@@ -4307,7 +4307,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@@ -4363,7 +4363,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@@ -4378,7 +4378,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@@ -4442,7 +4442,7 @@ static int apply_patch(struct apply_state *state,\n \t\t\tlistp = &patch->next;\n \t\t}\n \t\telse {\n-\t\t\tif (apply_verbosely)\n+\t\t\tif (state->apply_verbosely)\n \t\t\t\tsay_patch_name(stderr, _(\"Skipped patch '%s'.\"), patch);\n \t\t\tfree_patch(patch);\n \t\t\tskipped_patch++;\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@@ -4635,7 +4635,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@@ -4663,7 +4663,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.2.490.g3dabe57\n"},{"id":"286260","messageId":"20160511131745.2914-17-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 16/94] builtin/apply: move 'update_index' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:27Z","receivedAt":"2016-05-11T13:16:27Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'update_index' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 45 ++++++++++++++++++++++++++-------------------\n 1 file changed, 26 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 97af6ea..635a9ff 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -39,6 +39,7 @@ struct apply_state {\n \tint check_index;\n \n \tint unidiff_zero;\n+\tint update_index;\n };\n \n /*\n@@ -51,7 +52,6 @@ static int newfd = -1;\n \n static int state_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@@ -4095,9 +4095,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@@ -4108,14 +4108,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@@ -4225,13 +4229,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@@ -4252,7 +4257,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@@ -4264,22 +4269,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@@ -4287,9 +4294,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@@ -4376,7 +4383,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 +4463,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 && newfd < 0)\n+\tstate->update_index = state->check_index && apply;\n+\tif (state->update_index && newfd < 0)\n \t\tnewfd = hold_locked_index(&lock_file, 1);\n \n \tif (state->check_index) {\n@@ -4727,7 +4734,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.2.490.g3dabe57\n"},{"id":"286255","messageId":"20160511131745.2914-18-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 17/94] builtin/apply: move 'allow_overlap' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:28Z","receivedAt":"2016-05-11T13:16:28Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'allow_overlap' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 635a9ff..8791b28 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -25,6 +25,7 @@ struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n \n+\tint allow_overlap;\n \tint apply_in_reverse;\n \tint apply_with_reject;\n \tint apply_verbosely;\n@@ -57,7 +58,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@@ -2632,7 +2632,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@@ -2697,7 +2698,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@@ -2945,7 +2946,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@@ -4640,7 +4641,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.2.490.g3dabe57\n"},{"id":"286182","messageId":"20160511131745.2914-19-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 18/94] builtin/apply: move 'cached' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:29Z","receivedAt":"2016-05-11T13:16:29Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'cached' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 8791b28..09af5dc 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -30,6 +30,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@@ -47,13 +50,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- *  --cached updates only the cache without ever touching the working tree.\n  */\n static int newfd = -1;\n \n static int state_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@@ -3269,7 +3270,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@@ -3542,7 +3543,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@@ -3560,9 +3561,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@@ -3570,7 +3571,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@@ -3608,7 +3609,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@@ -4102,7 +4103,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@@ -4135,7 +4136,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@@ -4187,9 +4188,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@@ -4267,7 +4272,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@@ -4611,7 +4616,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@@ -4663,7 +4668,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@@ -4676,7 +4681,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.2.490.g3dabe57\n"},{"id":"286259","messageId":"20160511131745.2914-20-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 19/94] builtin/apply: move 'diffstat' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:30Z","receivedAt":"2016-05-11T13:16:30Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'diffstat' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 09af5dc..43c7198 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -33,6 +33,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@@ -47,7 +50,6 @@ 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@@ -55,7 +57,6 @@ static int newfd = -1;\n \n static int state_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@@ -4493,7 +4494,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@@ -4604,7 +4605,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@@ -4677,7 +4678,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.2.490.g3dabe57\n"},{"id":"286258","messageId":"20160511131745.2914-21-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 20/94] builtin/apply: move 'numstat' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:31Z","receivedAt":"2016-05-11T13:16:31Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'numstat' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 43c7198..887c5d0 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -36,6 +36,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@@ -50,14 +53,12 @@ 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 static int newfd = -1;\n \n static int state_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@@ -4497,7 +4498,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@@ -4609,7 +4610,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@@ -4678,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 || 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.2.490.g3dabe57\n"},{"id":"286253","messageId":"20160511131745.2914-22-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 21/94] builtin/apply: move 'summary' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:32Z","receivedAt":"2016-05-11T13:16:32Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'summary' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 887c5d0..6216723 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -39,6 +39,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@@ -59,7 +61,6 @@ static int newfd = -1;\n \n static int state_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@@ -4501,7 +4502,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@@ -4612,7 +4613,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@@ -4679,7 +4680,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.2.490.g3dabe57\n"},{"id":"286254","messageId":"20160511131745.2914-23-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 22/94] builtin/apply: move 'threeway' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:33Z","receivedAt":"2016-05-11T13:16:33Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'threeway' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 6216723..3650922 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -40,6 +40,7 @@ struct apply_state {\n \tint numstat;\n \n \tint summary;\n+\tint threeway;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -63,7 +64,6 @@ static int state_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@@ -3501,7 +3501,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@@ -3796,7 +3796,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@@ -4625,7 +4625,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@@ -4669,11 +4669,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.2.490.g3dabe57\n"},{"id":"286183","messageId":"20160511131745.2914-24-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 23/94] builtin/apply: move 'no_add' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:34Z","receivedAt":"2016-05-11T13:16:34Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'no_add' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 3650922..d699cd9 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -41,6 +41,7 @@ struct apply_state {\n \n \tint summary;\n \tint threeway;\n+\tint no_add;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -63,7 +64,6 @@ static int newfd = -1;\n static int state_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@@ -2792,7 +2792,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@@ -4605,7 +4605,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.2.490.g3dabe57\n"},{"id":"286181","messageId":"20160511131745.2914-25-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 24/94] builtin/apply: move 'unsafe_paths' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:35Z","receivedAt":"2016-05-11T13:16:35Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'unsafe_paths' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 d699cd9..9209af4 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -54,6 +54,7 @@ struct apply_state {\n \n \tint unidiff_zero;\n \tint update_index;\n+\tint unsafe_paths;\n };\n \n /*\n@@ -64,7 +65,6 @@ static int newfd = -1;\n static int state_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@@ -3837,7 +3837,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@@ -4621,7 +4621,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@@ -4690,7 +4690,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.2.490.g3dabe57\n"},{"id":"286184","messageId":"20160511131745.2914-26-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 25/94] builtin/apply: move 'line_termination' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:36Z","receivedAt":"2016-05-11T13:16:36Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'line_termination' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 12 +++++++-----\n 1 file changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 9209af4..d699d1e 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -55,6 +55,7 @@ struct apply_state {\n \tint unidiff_zero;\n \tint update_index;\n \tint unsafe_paths;\n+\tint line_termination;\n };\n \n /*\n@@ -66,7 +67,6 @@ static int state_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@@ -3987,7 +3987,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@@ -3996,7 +3997,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@@ -4500,7 +4501,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@@ -4575,6 +4576,7 @@ static void init_apply_state(struct apply_state *state, 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->line_termination = '\\n';\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n@@ -4630,7 +4632,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-- \n2.8.2.490.g3dabe57\n"},{"id":"286249","messageId":"20160511131745.2914-27-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 26/94] builtin/apply: move 'fake_ancestor' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:37Z","receivedAt":"2016-05-11T13:16:37Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'fake_ancestor' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nBy the way remove a 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\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 13 +++++--------\n 1 file changed, 5 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex d699d1e..6f9a090 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -42,6 +42,7 @@ struct apply_state {\n \tint summary;\n \tint threeway;\n \tint no_add;\n+\tconst char *fake_ancestor;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -58,15 +59,11 @@ 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 static int newfd = -1;\n \n static int state_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@@ -4494,8 +4491,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@@ -4629,7 +4626,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.2.490.g3dabe57\n"},{"id":"286251","messageId":"20160511131745.2914-28-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 27/94] builtin/apply: move 'p_context' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:38Z","receivedAt":"2016-05-11T13:16:38Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'p_context' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 6f9a090..2ba2b21 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -57,6 +57,8 @@ struct apply_state {\n \tint update_index;\n \tint unsafe_paths;\n \tint line_termination;\n+\n+\tunsigned int p_context;\n };\n \n static int newfd = -1;\n@@ -64,7 +66,6 @@ static int newfd = -1;\n static int state_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@@ -2880,7 +2881,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@@ -4574,6 +4575,7 @@ static void init_apply_state(struct apply_state *state, const char *prefix)\n \tstate->prefix = prefix;\n \tstate->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n \tstate->line_termination = '\\n';\n+\tstate->p_context = UINT_MAX;\n \n \tgit_apply_config();\n \tif (apply_default_whitespace)\n@@ -4631,7 +4633,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-- \n2.8.2.490.g3dabe57\n"},{"id":"286252","messageId":"20160511131745.2914-29-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 28/94] builtin/apply: move 'apply' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:39Z","receivedAt":"2016-05-11T13:16:39Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'apply' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 2ba2b21..a3db284 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -25,6 +25,7 @@ struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n \n+\tint apply;\n \tint allow_overlap;\n \tint apply_in_reverse;\n \tint apply_with_reject;\n@@ -65,7 +66,7 @@ static int newfd = -1;\n \n static int state_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@@ -135,10 +136,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@@ -2067,7 +2069,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\"), state_linenr);\n \t}\n@@ -2925,7 +2927,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@@ -4469,9 +4471,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 && newfd < 0)\n \t\tnewfd = hold_locked_index(&lock_file, 1);\n \n@@ -4480,12 +4482,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@@ -4574,6 +4576,7 @@ static void init_apply_state(struct apply_state *state, 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->line_termination = '\\n';\n \tstate->p_context = UINT_MAX;\n \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.2.490.g3dabe57\n"},{"id":"286250","messageId":"20160511131745.2914-30-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 29/94] builtin/apply: move 'patch_input_file' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:40Z","receivedAt":"2016-05-11T13:16:40Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'patch_input_file' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 27 +++++++++++++++++----------\n 1 file changed, 17 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex a3db284..e43da9c 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -44,6 +44,7 @@ struct apply_state {\n \tint threeway;\n \tint no_add;\n \tconst char *fake_ancestor;\n+\tconst char *patch_input_file;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -88,7 +89,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@@ -1534,7 +1534,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 linenr)\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 linenr)\n {\n \tchar *err;\n \n@@ -1548,15 +1552,18 @@ 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\tstate->patch_input_file, linenr, 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, state_linenr);\n+\trecord_ws_error(state, result, line + 1, len - 2, state_linenr);\n }\n \n /*\n@@ -1611,12 +1618,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@@ -1624,7 +1631,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@@ -2913,7 +2920,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@@ -4436,7 +4443,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.2.490.g3dabe57\n"},{"id":"286185","messageId":"20160511131745.2914-31-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 30/94] builtin/apply: move 'limit_by_name' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:41Z","receivedAt":"2016-05-11T13:16:41Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'limit_by_name' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 22 +++++++++++++---------\n 1 file changed, 13 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex e43da9c..14bbcc2 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -45,6 +45,7 @@ struct apply_state {\n \tint no_add;\n \tconst char *fake_ancestor;\n \tconst char *patch_input_file;\n+\tstruct string_list limit_by_name;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -1967,13 +1968,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@@ -1991,8 +1993,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@@ -4529,14 +4531,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@@ -4607,10 +4611,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.2.490.g3dabe57\n"},{"id":"286187","messageId":"20160511131745.2914-32-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 31/94] builtin/apply: move 'has_include' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:42Z","receivedAt":"2016-05-11T13:16:42Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'has_include' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 14bbcc2..f2ee8bf 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -46,6 +46,7 @@ struct apply_state {\n \tconst char *fake_ancestor;\n \tconst char *patch_input_file;\n \tstruct string_list limit_by_name;\n+\tint has_include;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -1968,7 +1969,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@@ -2004,7 +2004,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@@ -4541,7 +4541,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.2.490.g3dabe57\n"},{"id":"286193","messageId":"20160511131745.2914-33-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 32/94] builtin/apply: move 'p_value' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:43Z","receivedAt":"2016-05-11T13:16:43Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'p_value' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 f2ee8bf..4e476d5 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -62,12 +62,12 @@ struct apply_state {\n \tint unsafe_paths;\n \tint line_termination;\n \n+\tint p_value;\n \tunsigned int p_context;\n };\n \n static int newfd = -1;\n \n-static int state_p_value = 1;\n static int p_value_known;\n \n static const char * const apply_usage[] = {\n@@ -888,24 +888,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\tstate_p_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, state_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, state_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, state_p_value);\n-\t\tname = find_name_traditional(second, first_name, state_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@@ -924,7 +924,9 @@ static void parse_traditional_patch(struct apply_state *state,\n \t\tdie(_(\"unable to find filename in patch at line %d\"), state_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@@ -941,10 +943,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 void gitdiff_verify_name(const char *line, int isnull, char **name, int side)\n+static void gitdiff_verify_name(struct apply_state *state,\n+\t\t\t\tconst char *line,\n+\t\t\t\tint isnull,\n+\t\t\t\tchar **name,\n+\t\t\t\tint side)\n {\n \tif (!*name && !isnull) {\n-\t\t*name = find_name(line, NULL, state_p_value, TERM_TAB);\n+\t\t*name = find_name(line, NULL, state->p_value, TERM_TAB);\n \t\treturn;\n \t}\n \n@@ -954,7 +960,7 @@ static void gitdiff_verify_name(const char *line, int isnull, char **name, int s\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n \t\t\t    *name, state_linenr);\n-\t\tanother = find_name(line, NULL, state_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@@ -967,81 +973,105 @@ static void gitdiff_verify_name(const char *line, int isnull, char **name, int s\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-\tgitdiff_verify_name(line, patch->is_new, &patch->old_name,\n+\tgitdiff_verify_name(state, line,\n+\t\t\t    patch->is_new, &patch->old_name,\n \t\t\t    DIFF_OLD_NAME);\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-\tgitdiff_verify_name(line, patch->is_delete, &patch->new_name,\n+\tgitdiff_verify_name(state, line,\n+\t\t\t    patch->is_delete, &patch->new_name,\n \t\t\t    DIFF_NEW_NAME);\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, state_p_value ? state_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, state_p_value ? state_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, state_p_value ? state_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, state_p_value ? state_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@@ -1049,7 +1079,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@@ -1057,7 +1089,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@@ -1094,7 +1128,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@@ -1103,15 +1139,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 (!state_p_value)\n+\tif (!state->p_value)\n \t\treturn (llen && line[0] == '/') ? NULL : line;\n \n-\tnslash = state_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@@ -1128,7 +1166,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@@ -1146,7 +1186,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@@ -1163,7 +1203,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@@ -1174,7 +1214,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@@ -1189,7 +1229,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@@ -1205,7 +1245,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@@ -1249,7 +1289,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@@ -1265,7 +1305,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@@ -1279,7 +1323,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@@ -1292,7 +1336,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, state_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@@ -1322,7 +1366,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@@ -1492,7 +1536,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@@ -1501,8 +1545,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       state_p_value),\n-\t\t\t\t\t    state_p_value, state_linenr);\n+\t\t\t\t\t       state->p_value),\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@@ -4546,9 +4590,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-\tstate_p_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@@ -4589,6 +4635,7 @@ static void init_apply_state(struct apply_state *state, const char *prefix)\n \tstate->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n \tstate->apply = 1;\n \tstate->line_termination = '\\n';\n+\tstate->p_value = 1;\n \tstate->p_context = UINT_MAX;\n \n \tgit_apply_config();\n@@ -4617,7 +4664,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-- \n2.8.2.490.g3dabe57\n"},{"id":"286192","messageId":"20160511131745.2914-34-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 33/94] builtin/apply: move 'p_value_known' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:44Z","receivedAt":"2016-05-11T13:16:44Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'p_value_known' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 4e476d5..30eea9c 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -63,13 +63,12 @@ struct apply_state {\n \tint line_termination;\n \n \tint p_value;\n+\tint p_value_known;\n \tunsigned int p_context;\n };\n \n static int newfd = -1;\n \n-static int p_value_known;\n-\n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n \tNULL\n@@ -882,14 +881,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@@ -4595,7 +4594,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.2.490.g3dabe57\n"},{"id":"286190","messageId":"20160511131745.2914-35-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 34/94] builtin/apply: move 'root' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:45Z","receivedAt":"2016-05-11T13:16:45Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'root' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 81 ++++++++++++++++++++++++++++++++++-----------------------\n 1 file changed, 48 insertions(+), 33 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 30eea9c..6b3540f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -47,6 +47,7 @@ struct apply_state {\n \tconst char *patch_input_file;\n \tstruct string_list limit_by_name;\n \tint has_include;\n+\tstruct strbuf root;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -90,8 +91,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@@ -481,7 +480,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_value)\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_value)\n {\n \tstruct strbuf name = STRBUF_INIT;\n \tchar *cp;\n@@ -505,8 +507,8 @@ static char *find_name_gnu(const char *line, const char *def, int p_value)\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@@ -669,8 +671,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_value, 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_value,\n+\t\t\t      const char *end,\n+\t\t\t      int terminate)\n {\n \tint len;\n \tconst char *start = NULL;\n@@ -708,32 +714,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_value, 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_value,\n+\t\t       int terminate)\n {\n \tif (*line == '\"') {\n-\t\tchar *name = find_name_gnu(line, def, p_value);\n+\t\tchar *name = find_name_gnu(state, line, def, p_value);\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(state, line, def, p_value, NULL, terminate);\n }\n \n-static char *find_name_traditional(const char *line, char *def, int p_value)\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_value)\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(state, line, def, p_value);\n \t\tif (name)\n \t\t\treturn name;\n \t}\n@@ -741,10 +754,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(state, line, def, p_value, 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(state, line, def, p_value, line + len, 0);\n }\n \n static int count_slashes(const char *cp)\n@@ -769,7 +782,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@@ -894,17 +907,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@@ -949,7 +962,7 @@ static void gitdiff_verify_name(struct apply_state *state,\n \t\t\t\tint side)\n {\n \tif (!*name && !isnull) {\n-\t\t*name = find_name(line, NULL, state->p_value, TERM_TAB);\n+\t\t*name = find_name(state, line, NULL, state->p_value, TERM_TAB);\n \t\treturn;\n \t}\n \n@@ -959,7 +972,7 @@ static void gitdiff_verify_name(struct apply_state *state,\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n \t\t\t    *name, state_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@@ -1034,7 +1047,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@@ -1044,7 +1057,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@@ -1054,7 +1067,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@@ -1064,7 +1077,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@@ -1323,8 +1336,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@@ -4621,9 +4634,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@@ -4636,6 +4650,7 @@ static void init_apply_state(struct apply_state *state, 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@@ -4719,7 +4734,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-- \n2.8.2.490.g3dabe57\n"},{"id":"286188","messageId":"20160511131745.2914-36-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 35/94] builtin/apply: move 'whitespace_error' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:46Z","receivedAt":"2016-05-11T13:16:46Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'whitespace_error' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 6b3540f..1684f25 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -66,6 +66,8 @@ struct apply_state {\n \tint p_value;\n \tint p_value_known;\n \tunsigned int p_context;\n+\n+\tint whitespace_error;\n };\n \n static int newfd = -1;\n@@ -81,7 +83,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@@ -1603,9 +1604,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@@ -2862,7 +2863,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@@ -4535,7 +4536,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@@ -4792,11 +4793,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@@ -4805,18 +4806,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.2.490.g3dabe57\n"},{"id":"286191","messageId":"20160511131745.2914-37-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 36/94] builtin/apply: move 'whitespace_option' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:47Z","receivedAt":"2016-05-11T13:16:47Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This will enable further refactoring, and it is more coherent and\nsimpler if all the option_parse_*() functions are passed a\n'struct apply_state' instance in opt->value.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\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 1684f25..4b9a5ff 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -67,6 +67,7 @@ struct apply_state {\n \tint p_value_known;\n \tunsigned int p_context;\n \n+\tconst char *whitespace_option;\n \tint whitespace_error;\n };\n \n@@ -4625,9 +4626,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@@ -4670,8 +4671,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@@ -4711,7 +4710,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@@ -4786,11 +4785,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.2.490.g3dabe57\n"},{"id":"286189","messageId":"20160511131745.2914-38-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 37/94] builtin/apply: remove whitespace_option arg from set_default_whitespace_mode()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:48Z","receivedAt":"2016-05-11T13:16:48Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"A previous change has move the whitespace_option variable from cmd_apply\ninto 'struct apply_state', so that we can now avoid passing it separately\nto set_default_whitespace_mode().\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 4b9a5ff..ab954b4 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -138,10 +138,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@@ -4785,11 +4784,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.2.490.g3dabe57\n"},{"id":"286186","messageId":"20160511131745.2914-39-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 38/94] builtin/apply: move 'squelch_whitespace_errors' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:49Z","receivedAt":"2016-05-11T13:16:49Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'squelch_whitespace_errors' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 ab954b4..f84e301 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -69,6 +69,7 @@ struct apply_state {\n \n \tconst char *whitespace_option;\n \tint whitespace_error;\n+\tint squelch_whitespace_errors;\n };\n \n static int newfd = -1;\n@@ -84,7 +85,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@@ -93,7 +93,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@@ -113,7 +113,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@@ -1605,8 +1605,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@@ -4626,9 +4626,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@@ -4651,11 +4650,12 @@ static void init_apply_state(struct apply_state *state, 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@@ -4792,10 +4792,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.2.490.g3dabe57\n"},{"id":"286247","messageId":"20160511131745.2914-40-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 39/94] builtin/apply: move 'applied_after_fixing_ws' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:50Z","receivedAt":"2016-05-11T13:16:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'applied_after_fixing_ws' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 f84e301..e68fd2c 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -70,6 +70,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 int newfd = -1;\n@@ -85,7 +86,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@@ -2868,7 +2868,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@@ -4806,11 +4806,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.2.490.g3dabe57\n"},{"id":"286248","messageId":"20160511131745.2914-41-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 40/94] builtin/apply: move 'ws_error_action' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:51Z","receivedAt":"2016-05-11T13:16:51Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'ws_error_action' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nSigned-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 e68fd2c..10d45c7 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@@ -71,6 +78,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 int newfd = -1;\n@@ -80,12 +89,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@@ -96,28 +99,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@@ -141,7 +144,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@@ -1676,12 +1679,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@@ -1689,7 +1692,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@@ -2402,7 +2405,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@@ -2423,7 +2427,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@@ -2495,7 +2499,7 @@ static int match_fragment(struct image *img,\n \t\treturn line_by_line_fuzzy_match(img, preimage, postimage,\n \t\t\t\t\t\ttry, try_lno, preimage_limit);\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@@ -2607,7 +2611,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@@ -2651,7 +2656,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@@ -2864,7 +2869,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@@ -2942,7 +2947,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@@ -2978,10 +2983,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@@ -2992,7 +2997,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@@ -4536,7 +4541,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@@ -4651,6 +4656,7 @@ static void init_apply_state(struct apply_state *state, 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@@ -4801,7 +4807,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.2.490.g3dabe57\n"},{"id":"286195","messageId":"20160511131745.2914-42-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 41/94] builtin/apply: move 'ws_ignore_action' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:52Z","receivedAt":"2016-05-11T13:16:52Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'ws_ignore_action' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 10d45c7..f8c3677 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@@ -80,6 +86,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 int newfd = -1;\n@@ -89,13 +96,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@@ -126,16 +126,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@@ -2495,7 +2496,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,\n \t\t\t\t\t\ttry, try_lno, preimage_limit);\n \n@@ -4618,12 +4619,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@@ -4657,13 +4659,14 @@ static void init_apply_state(struct apply_state *state, 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 \n int cmd_apply(int argc, const char **argv, const char *prefix_)\n@@ -4718,10 +4721,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-- \n2.8.2.490.g3dabe57\n"},{"id":"286194","messageId":"20160511131745.2914-43-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 42/94] builtin/apply: move 'max_change' and 'max_len' into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:53Z","receivedAt":"2016-05-11T13:16:53Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'max_change' and 'max_len'\nvariables should not be static and global to the file. Let's move\nthem into 'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 f8c3677..deba14c 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -76,6 +76,14 @@ struct apply_state {\n \tint unsafe_paths;\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@@ -148,13 +156,6 @@ static void set_default_whitespace_mode(struct apply_state *state)\n \t\tstate->ws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);\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@@ -2179,7 +2180,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@@ -2190,7 +2191,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@@ -2213,13 +2214,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@@ -4045,7 +4046,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@@ -4053,7 +4054,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@@ -4151,25 +4152,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@@ -4526,7 +4527,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@@ -4570,7 +4571,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.2.490.g3dabe57\n"},{"id":"286246","messageId":"20160511131745.2914-44-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 43/94] builtin/apply: move 'state_linenr' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:54Z","receivedAt":"2016-05-11T13:16:54Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'state_linenr' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 deba14c..5c003a1 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -84,6 +84,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@@ -156,13 +163,6 @@ static void set_default_whitespace_mode(struct apply_state *state)\n \t\tstate->ws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);\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 state_linenr = 1;\n-\n /*\n  * This represents one \"hunk\" from a patch, starting with\n  * \"@@ -oldpos,oldlines +newpos,newlines @@\" marker.  The\n@@ -939,7 +939,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\"), state_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@@ -977,17 +977,17 @@ static void gitdiff_verify_name(struct apply_state *state,\n \t\tchar *another;\n \t\tif (isnull)\n \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n-\t\t\t    *name, state_linenr);\n+\t\t\t    *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\"), state_linenr);\n+\t\t\t    _(\"git apply: bad git-diff - inconsistent old filename on line %d\"), state->linenr);\n \t\tfree(another);\n \t} else {\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\"), state_linenr);\n+\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null on line %d\"), state->linenr);\n \t}\n }\n \n@@ -1350,8 +1350,8 @@ static int parse_git_header(struct apply_state *state,\n \n \tline += len;\n \tsize -= len;\n-\tstate_linenr++;\n-\tfor (offset = len ; size > 0 ; offset += len, size -= len, line += len, state_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@@ -1522,7 +1522,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, state_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@@ -1543,7 +1543,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    state_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@@ -1564,13 +1564,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, state_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)\", state_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@@ -1592,7 +1592,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\tstate_linenr += 2;\n+\t\tstate->linenr += 2;\n \t\treturn offset;\n \t}\n \treturn -1;\n@@ -1627,7 +1627,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, state_linenr);\n+\trecord_ws_error(state, result, line + 1, len - 2, state->linenr);\n }\n \n /*\n@@ -1660,11 +1660,11 @@ static int parse_fragment(struct apply_state *state,\n \t/* Parse the thing.. */\n \tline += len;\n \tsize -= len;\n-\tstate_linenr++;\n+\tstate->linenr++;\n \tadded = deleted = 0;\n \tfor (offset = len;\n \t     0 < size;\n-\t     offset += len, size -= len, line += len, state_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@@ -1763,10 +1763,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 = state_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\"), state_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@@ -1852,7 +1852,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@@ -1894,13 +1895,13 @@ static struct fragment *parse_binary_hunk(char **buf_p,\n \telse\n \t\treturn NULL;\n \n-\tstate_linenr++;\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\tstate_linenr++;\n+\t\tstate->linenr++;\n \t\tif (llen == 1) {\n \t\t\t/* consume the blank line */\n \t\t\tbuffer++;\n@@ -1954,7 +1955,7 @@ 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      state_linenr-1, llen-1, buffer);\n+\t      state->linenr-1, llen-1, buffer);\n \treturn NULL;\n }\n \n@@ -1963,7 +1964,10 @@ static struct fragment *parse_binary_hunk(char **buf_p,\n  *   -1 in case of error,\n  *   the length of the parsed binary patch otherwise\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@@ -1984,15 +1988,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\"), state_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@@ -2107,8 +2111,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\tstate_linenr++;\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 < 0)\n \t\t\t\treturn -1;\n@@ -2128,7 +2132,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\tstate_linenr++;\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@@ -2142,7 +2146,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\"), state_linenr);\n+\t\t\tdie(_(\"patch with only garbage at line %d\"), state->linenr);\n \t}\n \n \treturn offset + hdrsize + patchsize;\n@@ -4661,6 +4665,7 @@ static void init_apply_state(struct apply_state *state, 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.2.490.g3dabe57\n"},{"id":"286198","messageId":"20160511131745.2914-45-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 44/94] builtin/apply: move 'fn_table' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:55Z","receivedAt":"2016-05-11T13:16:55Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'fn_table' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 5c003a1..506e9ec 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -91,6 +91,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@@ -282,13 +288,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@@ -3218,14 +3217,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@@ -3257,7 +3256,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@@ -3267,7 +3266,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@@ -3276,12 +3275,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@@ -3289,7 +3288,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@@ -3310,7 +3309,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@@ -3318,7 +3319,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@@ -3387,7 +3388,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@@ -3583,7 +3584,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@@ -3617,7 +3618,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@@ -3863,7 +3864,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@@ -3941,7 +3942,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@@ -4585,7 +4586,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.2.490.g3dabe57\n"},{"id":"286196","messageId":"20160511131745.2914-46-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 45/94] builtin/apply: move 'symlink_changes' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:56Z","receivedAt":"2016-05-11T13:16:56Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'symlink_changes' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 49 +++++++++++++++++++++++++++----------------------\n 1 file changed, 27 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 506e9ec..14286d2 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@@ -61,6 +75,7 @@ struct apply_state {\n \tstruct string_list limit_by_name;\n \tint has_include;\n \tstruct strbuf root;\n+\tstruct string_list symlink_changes;\n \n \t/*\n \t *  --check turns on checking that the working tree matches the\n@@ -3713,52 +3728,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@@ -3772,7 +3777,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@@ -3941,7 +3946,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.2.490.g3dabe57\n"},{"id":"286197","messageId":"20160511131745.2914-47-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 46/94] builtin/apply: move 'state' check into check_apply_state()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:57Z","receivedAt":"2016-05-11T13:16:57Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality we should provide a function\nto check that the values in a 'struct apply_state' instance are\ncoherent. Let's move the code to do that into a new\ncheck_apply_state() function.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 14286d2..e5f76d8 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4681,11 +4681,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@@ -4765,28 +4792,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.2.490.g3dabe57\n"},{"id":"286199","messageId":"20160511131745.2914-48-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 47/94] builtin/apply: move applying patches into apply_all_patches()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:58Z","receivedAt":"2016-05-11T13:16:58Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality we should provide a function to\napply many patches. Let's move the code to do that into a new\napply_all_patches() function.\n\nReviewed-by: Stefan Beller <sbeller@google.com>\nSigned-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 e5f76d8..67c64a5 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4709,13 +4709,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, &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@@ -4794,61 +4860,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, &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.2.490.g3dabe57\n"},{"id":"286201","messageId":"20160511131745.2914-49-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:16:59Z","receivedAt":"2016-05-11T13:16:59Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This is just a small cleanup.\n\nSigned-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 67c64a5..2aea8ba 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4778,7 +4778,7 @@ static int apply_all_patches(struct apply_state *state,\n \treturn !!errs;\n }\n \n-int cmd_apply(int argc, const char **argv, const char *prefix_)\n+int cmd_apply(int argc, const char **argv, const char *prefix)\n {\n \tint force_apply = 0;\n \tint options = 0;\n@@ -4853,7 +4853,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)\n \t\tOPT_END()\n \t};\n \n-\tinit_apply_state(&state, prefix_);\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.2.490.g3dabe57\n"},{"id":"286202","messageId":"20160511131745.2914-50-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 49/94] builtin/apply: move 'lock_file' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:00Z","receivedAt":"2016-05-11T13:17:00Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"We cannot have a 'struct lock_file' allocated on the stack, as lockfile.c\nkeeps a linked list of all created lock_file structures. So let's make the\n'lock_file' variable a pointer to a 'struct lock_file'\n\nAs the same instance of this struct can be reused, let's add an argument\nto init_apply_state(), so that the caller can supply the same instance to\ndifferent calls. And let's alloc an instance in init_apply_state(), if the\ncaller doesn't want to supply one.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 19 +++++++++++++------\n 1 file changed, 13 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 2aea8ba..cad2c56 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -52,6 +52,12 @@ struct apply_state {\n \tconst char *prefix;\n \tint prefix_length;\n \n+\t/*\n+\t * Since lockfile.c keeps a linked list of all created\n+\t * lock_file structures, it isn't safe to free(lock_file).\n+\t */\n+\tstruct lock_file *lock_file;\n+\n \tint apply;\n \tint allow_overlap;\n \tint apply_in_reverse;\n@@ -4504,8 +4510,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@@ -4558,7 +4562,7 @@ static int apply_patch(struct apply_state *state,\n \n \tstate->update_index = state->check_index && state->apply;\n \tif (state->update_index && newfd < 0)\n-\t\tnewfd = hold_locked_index(&lock_file, 1);\n+\t\tnewfd = hold_locked_index(state->lock_file, 1);\n \n \tif (state->check_index) {\n \t\tif (read_cache() < 0)\n@@ -4659,11 +4663,14 @@ 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+static void init_apply_state(struct apply_state *state,\n+\t\t\t     const char *prefix,\n+\t\t\t     struct lock_file *lock_file)\n {\n \tmemset(state, 0, sizeof(*state));\n \tstate->prefix = prefix;\n \tstate->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n+\tstate->lock_file = lock_file ? lock_file : xcalloc(1, sizeof(*lock_file));\n \tstate->apply = 1;\n \tstate->line_termination = '\\n';\n \tstate->p_value = 1;\n@@ -4771,7 +4778,7 @@ static int apply_all_patches(struct apply_state *state,\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@@ -4853,7 +4860,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n-\tinit_apply_state(&state, prefix);\n+\tinit_apply_state(&state, prefix, NULL);\n \n \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286242","messageId":"20160511131745.2914-51-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 50/94] builtin/apply: move 'newfd' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:01Z","receivedAt":"2016-05-11T13:17:01Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify the apply functionality the 'newfd' variable should\nnot be static and global to the file. Let's move it into\n'struct apply_state'.\n\nSigned-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 cad2c56..ec55768 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -57,6 +57,7 @@ struct apply_state {\n \t * lock_file structures, it isn't safe to free(lock_file).\n \t */\n \tstruct lock_file *lock_file;\n+\tint newfd;\n \n \tint apply;\n \tint allow_overlap;\n@@ -131,8 +132,6 @@ struct apply_state {\n \tenum ws_ignore ws_ignore_action;\n };\n \n-static int newfd = -1;\n-\n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n \tNULL\n@@ -4561,8 +4560,8 @@ static int apply_patch(struct apply_state *state,\n \t\tstate->apply = 0;\n \n \tstate->update_index = state->check_index && state->apply;\n-\tif (state->update_index && newfd < 0)\n-\t\tnewfd = hold_locked_index(state->lock_file, 1);\n+\tif (state->update_index && state->newfd < 0)\n+\t\tstate->newfd = hold_locked_index(state->lock_file, 1);\n \n \tif (state->check_index) {\n \t\tif (read_cache() < 0)\n@@ -4671,6 +4670,7 @@ static void init_apply_state(struct apply_state *state,\n \tstate->prefix = prefix;\n \tstate->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n \tstate->lock_file = lock_file ? lock_file : xcalloc(1, sizeof(*lock_file));\n+\tstate->newfd = -1;\n \tstate->apply = 1;\n \tstate->line_termination = '\\n';\n \tstate->p_value = 1;\n@@ -4780,6 +4780,7 @@ static int apply_all_patches(struct apply_state *state,\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\tstate->newfd = -1;\n \t}\n \n \treturn !!errs;\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286245","messageId":"20160511131745.2914-52-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 51/94] builtin/apply: make apply_patch() return -1 instead of die()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:02Z","receivedAt":"2016-05-11T13:17:02Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors\nto the caller instead of die()ing.\n\nAs a first step in this direction, let's make apply_patch() return\n-1 in case of errors instead of dying. For now its only caller\napply_all_patches() will exit(1) when apply_patch() return -1.\n\nIn a later patch, apply_all_patches() will return -1 too instead of\nexiting.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 54 +++++++++++++++++++++++++++++++++++++++---------------\n 1 file changed, 39 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex ec55768..d95630c 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4512,6 +4512,14 @@ static int write_out_results(struct apply_state *state, struct patch *list)\n #define INACCURATE_EOF\t(1<<0)\n #define RECOUNT\t\t(1<<1)\n \n+/*\n+ * Try to apply a patch.\n+ *\n+ * Returns:\n+ *  -1 if an error happened\n+ *   0 if the patch applied\n+ *   1 if the patch did not apply\n+ */\n static int apply_patch(struct apply_state *state,\n \t\t       int fd,\n \t\t       const char *filename,\n@@ -4521,6 +4529,7 @@ static int apply_patch(struct apply_state *state,\n \tstruct strbuf buf = STRBUF_INIT; /* owns the patch text */\n \tstruct patch *list = NULL, **listp = &list;\n \tint skipped_patch = 0;\n+\tint res = 0;\n \n \tstate->patch_input_file = filename;\n \tread_patch_file(&buf, fd);\n@@ -4553,8 +4562,10 @@ static int apply_patch(struct apply_state *state,\n \t\toffset += nr;\n \t}\n \n-\tif (!list && !skipped_patch)\n-\t\tdie(_(\"unrecognized input\"));\n+\tif (!list && !skipped_patch) {\n+\t\tres = error(_(\"unrecognized input\"));\n+\t\tgoto end;\n+\t}\n \n \tif (state->whitespace_error && (state->ws_error_action == die_on_ws_error))\n \t\tstate->apply = 0;\n@@ -4563,21 +4574,22 @@ static int apply_patch(struct apply_state *state,\n \tif (state->update_index && state->newfd < 0)\n \t\tstate->newfd = hold_locked_index(state->lock_file, 1);\n \n-\tif (state->check_index) {\n-\t\tif (read_cache() < 0)\n-\t\t\tdie(_(\"unable to read index file\"));\n+\tif (state->check_index && read_cache() < 0) {\n+\t\tres = error(_(\"unable to read index file\"));\n+\t\tgoto end;\n \t}\n \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+\t    !state->apply_with_reject) {\n+\t\tres = -1;\n+\t\tgoto end;\n+\t}\n \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-\t\treturn 1;\n+\t\tres = state->apply_with_reject ? -1 : 1;\n+\t\tgoto end;\n \t}\n \n \tif (state->fake_ancestor)\n@@ -4592,10 +4604,11 @@ static int apply_patch(struct apply_state *state,\n \tif (state->summary)\n \t\tsummary_patch_list(list);\n \n+end:\n \tfree_patch_list(list);\n \tstrbuf_release(&buf);\n \tstring_list_clear(&state->fn_table, 0);\n-\treturn 0;\n+\treturn res;\n }\n \n static void git_apply_config(void)\n@@ -4722,6 +4735,7 @@ static int apply_all_patches(struct apply_state *state,\n \t\t\t     int options)\n {\n \tint i;\n+\tint res;\n \tint errs = 0;\n \tint read_stdin = 1;\n \n@@ -4730,7 +4744,10 @@ static int apply_all_patches(struct apply_state *state,\n \t\tint fd;\n \n \t\tif (!strcmp(arg, \"-\")) {\n-\t\t\terrs |= apply_patch(state, 0, \"<stdin>\", options);\n+\t\t\tres = apply_patch(state, 0, \"<stdin>\", options);\n+\t\t\tif (res < 0)\n+\t\t\t\texit(1);\n+\t\t\terrs |= res;\n \t\t\tread_stdin = 0;\n \t\t\tcontinue;\n \t\t} else if (0 < state->prefix_length)\n@@ -4743,12 +4760,19 @@ static int apply_all_patches(struct apply_state *state,\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\tres = apply_patch(state, fd, arg, options);\n+\t\tif (res < 0)\n+\t\t\texit(1);\n+\t\terrs |= res;\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 (read_stdin) {\n+\t\tres = apply_patch(state, 0, \"<stdin>\", options);\n+\t\tif (res < 0)\n+\t\t\texit(1);\n+\t\terrs |= res;\n+\t}\n \n \tif (state->whitespace_error) {\n \t\tif (state->squelch_whitespace_errors &&\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286244","messageId":"20160511131745.2914-53-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 52/94] builtin/apply: read_patch_file() return -1 instead of die()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:03Z","receivedAt":"2016-05-11T13:17:03Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing. Let's do that by using error() instead\nof die()ing in read_patch_file().\n\nSigned-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 d95630c..a166d70 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -445,10 +445,10 @@ static void say_patch_name(FILE *output, const char *fmt, struct patch *patch)\n \n #define SLOP (16)\n \n-static void read_patch_file(struct strbuf *sb, int fd)\n+static int read_patch_file(struct strbuf *sb, int fd)\n {\n \tif (strbuf_read(sb, fd, 0) < 0)\n-\t\tdie_errno(\"git apply: failed to read\");\n+\t\treturn error(\"git apply: failed to read: %s\", strerror(errno));\n \n \t/*\n \t * Make sure that we have some slop in the buffer\n@@ -457,6 +457,7 @@ static void read_patch_file(struct strbuf *sb, int fd)\n \t */\n \tstrbuf_grow(sb, SLOP);\n \tmemset(sb->buf + sb->len, 0, SLOP);\n+\treturn 0;\n }\n \n static unsigned long linelen(const char *buffer, unsigned long size)\n@@ -4532,7 +4533,8 @@ static int apply_patch(struct apply_state *state,\n \tint res = 0;\n \n \tstate->patch_input_file = filename;\n-\tread_patch_file(&buf, fd);\n+\tif (read_patch_file(&buf, fd))\n+\t\treturn -1;\n \toffset = 0;\n \twhile (offset < buf.len) {\n \t\tstruct patch *patch;\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286243","messageId":"20160511131745.2914-54-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 53/94] builtin/apply: make find_header() return -1 instead of die()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:04Z","receivedAt":"2016-05-11T13:17:04Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin builtin/apply.c, find_header() should return -1 using error()\ninstead of calling die().\n\nUnfortunately find_header() already returns -1 when no header is found,\nso let's make it return -2 instead in this case.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c       | 33 ++++++++++++++++++++++-----------\n t/t4254-am-corrupt.sh |  2 +-\n 2 files changed, 23 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex a166d70..4212705 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -1529,6 +1529,14 @@ static int parse_fragment_header(const char *line, int len, struct fragment *fra\n \treturn offset;\n }\n \n+/*\n+ * Find file diff header\n+ *\n+ * Returns:\n+ *  -1 in case of error\n+ *  -2 if no header was found\n+ *   the size of the header in bytes (called \"offset\") otherwise\n+ */\n static int find_header(struct apply_state *state,\n \t\t       const char *line,\n \t\t       unsigned long size,\n@@ -1562,8 +1570,8 @@ static int find_header(struct apply_state *state,\n \t\t\tstruct fragment dummy;\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    state->linenr, (int)len-1, line);\n+\t\t\treturn error(_(\"patch fragment without header at line %d: %.*s\"),\n+\t\t\t\t     state->linenr, (int)len-1, line);\n \t\t}\n \n \t\tif (size < len + 6)\n@@ -1579,18 +1587,18 @@ static int find_header(struct apply_state *state,\n \t\t\t\tcontinue;\n \t\t\tif (!patch->old_name && !patch->new_name) {\n \t\t\t\tif (!patch->def_name)\n-\t\t\t\t\tdie(Q_(\"git diff header lacks filename information when removing \"\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       state->p_value),\n-\t\t\t\t\t    state->p_value, state->linenr);\n+\t\t\t\t\treturn error(Q_(\"git diff header lacks filename information when removing \"\n+\t\t\t\t\t\t\t\"%d leading pathname component (line %d)\",\n+\t\t\t\t\t\t\t\"git diff header lacks filename information when removing \"\n+\t\t\t\t\t\t\t\"%d leading pathname components (line %d)\",\n+\t\t\t\t\t\t\tstate->p_value),\n+\t\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)\", state->linenr);\n+\t\t\t\treturn error(\"git diff header lacks filename information \"\n+\t\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@@ -1615,7 +1623,7 @@ static int find_header(struct apply_state *state,\n \t\tstate->linenr += 2;\n \t\treturn offset;\n \t}\n-\treturn -1;\n+\treturn -2;\n }\n \n static void record_ws_error(struct apply_state *state,\n@@ -2106,6 +2114,9 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \tint hdrsize, patchsize;\n \tint offset = find_header(state, buffer, size, &hdrsize, patch);\n \n+\tif (offset == -1)\n+\t\texit(1);\n+\n \tif (offset < 0)\n \t\treturn offset;\n \ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 85716dd..9bd7dd2 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -29,7 +29,7 @@ test_expect_success 'try to apply corrupted patch' '\n '\n \n test_expect_success 'compare diagnostic; ensure file is still here' '\n-\techo \"fatal: git diff header lacks filename information (line 4)\" >expected &&\n+\techo \"error: git diff header lacks filename information (line 4)\" >expected &&\n \ttest_path_is_file f &&\n \ttest_cmp expected actual\n '\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286200","messageId":"20160511131745.2914-55-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 54/94] builtin/apply: make parse_chunk() return a negative integer on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:05Z","receivedAt":"2016-05-11T13:17:05Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing or exit()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin builtin/apply.c, find_header() should return -1 instead of calling\ndie() or exit().\n\nAs parse_chunk() is called only by apply_patch() which already\nreturns -1 when an error happened, let's make apply_patch() return -1\nwhen parse_chunk() returns -1.\n\nIf find_header() returns -2 because no patch header has been found, it\nis ok for parse_chunk() to also return -2. If find_header() returns -1\nbecause an error happened, it is ok for parse_chunk() to do the same.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 21 +++++++++++++--------\n 1 file changed, 13 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 4212705..2380472 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -2101,22 +2101,22 @@ static int use_patch(struct apply_state *state, struct patch *p)\n \treturn !state->has_include;\n }\n \n-\n /*\n  * Read the patch text in \"buffer\" that extends for \"size\" bytes; stop\n  * reading after seeing a single patch (i.e. changes to a single file).\n  * Create fragments (i.e. patch hunks) and hang them to the given patch.\n- * Return the number of bytes consumed, so that the caller can call us\n- * again for the next patch.\n+ *\n+ * Returns:\n+ *   -1 on error,\n+ *   -2 if no header was found,\n+ *   the number of bytes consumed otherwise,\n+ *     so that the caller can call us again for the next patch.\n  */\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(state, buffer, size, &hdrsize, patch);\n \n-\tif (offset == -1)\n-\t\texit(1);\n-\n \tif (offset < 0)\n \t\treturn offset;\n \n@@ -2176,8 +2176,9 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\t * empty to us here.\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\"), state->linenr);\n+\t\t    (!patch->is_binary && !metadata_changes(patch))) {\n+\t\t\treturn error(_(\"patch with only garbage at line %d\"), state->linenr);\n+\t\t}\n \t}\n \n \treturn offset + hdrsize + patchsize;\n@@ -4557,6 +4558,10 @@ 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\tfree_patch(patch);\n+\t\t\tif (nr == -1) {\n+\t\t\t\tres = -1;\n+\t\t\t\tgoto end;\n+\t\t\t}\n \t\t\tbreak;\n \t\t}\n \t\tif (state->apply_in_reverse)\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286211","messageId":"20160511131745.2914-56-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 55/94] builtin/apply: make parse_single_patch() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:06Z","receivedAt":"2016-05-11T13:17:06Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin builtin/apply.c, parse_single_patch() should return -1 instead of\ncalling die().\n\nLet's do that by using error() and let's adjust the related test\ncases accordingly.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c        | 17 +++++++++++++----\n t/t4012-diff-binary.sh |  4 ++--\n 2 files changed, 15 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 2380472..58bcfeb 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -1776,6 +1776,10 @@ static int parse_fragment(struct apply_state *state,\n  *\n  * The (fragment->patch, fragment->size) pair points into the memory given\n  * by the caller, not a copy, when we return.\n+ *\n+ * Returns:\n+ *   -1 in case of error,\n+ *   the number of bytes in the patch otherwise.\n  */\n static int parse_single_patch(struct apply_state *state,\n \t\t\t      const char *line,\n@@ -1793,8 +1797,10 @@ static int parse_single_patch(struct apply_state *state,\n \t\tfragment = xcalloc(1, sizeof(*fragment));\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\"), state->linenr);\n+\t\tif (len <= 0) {\n+\t\t\tfree(fragment);\n+\t\t\treturn error(_(\"corrupt patch at line %d\"), state->linenr);\n+\t\t}\n \t\tfragment->patch = line;\n \t\tfragment->size = len;\n \t\toldlines += fragment->oldlines;\n@@ -1830,9 +1836,9 @@ static int parse_single_patch(struct apply_state *state,\n \t\tpatch->is_delete = 0;\n \n \tif (0 < patch->is_new && oldlines)\n-\t\tdie(_(\"new file %s depends on old contents\"), patch->new_name);\n+\t\treturn error(_(\"new file %s depends on old contents\"), patch->new_name);\n \tif (0 < patch->is_delete && newlines)\n-\t\tdie(_(\"deleted file %s still has contents\"), patch->old_name);\n+\t\treturn error(_(\"deleted file %s still has contents\"), patch->old_name);\n \tif (!patch->is_delete && !newlines && context)\n \t\tfprintf_ln(stderr,\n \t\t\t   _(\"** warning: \"\n@@ -2134,6 +2140,9 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n \t\t\t\t       size - offset - hdrsize,\n \t\t\t\t       patch);\n \n+\tif (patchsize < 0)\n+\t\treturn -1;\n+\n \tif (!patchsize) {\n \t\tstatic const char git_binary[] = \"GIT binary patch\\n\";\n \t\tint hd = hdrsize + offset;\ndiff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh\nindex 643d729..0a8af76 100755\n--- a/t/t4012-diff-binary.sh\n+++ b/t/t4012-diff-binary.sh\n@@ -68,7 +68,7 @@ test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '\n \tsed -e \"s/-CIT/xCIT/\" <output >broken &&\n \ttest_must_fail git apply --stat --summary broken 2>detected &&\n \tdetected=$(cat detected) &&\n-\tdetected=$(expr \"$detected\" : \"fatal.*at line \\\\([0-9]*\\\\)\\$\") &&\n+\tdetected=$(expr \"$detected\" : \"error.*at line \\\\([0-9]*\\\\)\\$\") &&\n \tdetected=$(sed -ne \"${detected}p\" broken) &&\n \ttest \"$detected\" = xCIT\n '\n@@ -77,7 +77,7 @@ test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '\n \tgit diff --binary | sed -e \"s/-CIT/xCIT/\" >broken &&\n \ttest_must_fail git apply --stat --summary broken 2>detected &&\n \tdetected=$(cat detected) &&\n-\tdetected=$(expr \"$detected\" : \"fatal.*at line \\\\([0-9]*\\\\)\\$\") &&\n+\tdetected=$(expr \"$detected\" : \"error.*at line \\\\([0-9]*\\\\)\\$\") &&\n \tdetected=$(sed -ne \"${detected}p\" broken) &&\n \ttest \"$detected\" = xCIT\n '\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286206","messageId":"20160511131745.2914-57-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 56/94] apply: move 'struct apply_state' to apply.h","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:07Z","receivedAt":"2016-05-11T13:17:07Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we must make 'struct apply_state'\nusable outside \"builtin/apply.c\".\n\nLet's do that by creating a new \"apply.h\" and moving\n'struct apply_state' there.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.h         | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n builtin/apply.c | 112 +-----------------------------------------------------\n 2 files changed, 116 insertions(+), 111 deletions(-)\n create mode 100644 apply.h\n\ndiff --git a/apply.h b/apply.h\nnew file mode 100644\nindex 0000000..aa11ea6\n--- /dev/null\n+++ b/apply.h\n@@ -0,0 +1,115 @@\n+#ifndef APPLY_H\n+#define APPLY_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+\n+enum ws_ignore {\n+\tignore_ws_none,\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+\n+\t/*\n+\t * Since lockfile.c keeps a linked list of all created\n+\t * lock_file structures, it isn't safe to free(lock_file).\n+\t */\n+\tstruct lock_file *lock_file;\n+\tint newfd;\n+\n+\tint apply;\n+\tint allow_overlap;\n+\tint apply_in_reverse;\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/* --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+\tint summary;\n+\tint threeway;\n+\tint no_add;\n+\tconst char *fake_ancestor;\n+\tconst char *patch_input_file;\n+\tstruct string_list limit_by_name;\n+\tint has_include;\n+\tstruct strbuf root;\n+\tstruct string_list symlink_changes;\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+\n+\t/* --index updates the cache as well. */\n+\tint check_index;\n+\n+\tint unidiff_zero;\n+\tint update_index;\n+\tint unsafe_paths;\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+\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+\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+\n+\tconst char *whitespace_option;\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+\tenum ws_ignore ws_ignore_action;\n+};\n+\n+#endif\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 58bcfeb..e42c8fe 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -20,117 +20,7 @@\n #include \"xdiff-interface.h\"\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-\n-enum ws_ignore {\n-\tignore_ws_none,\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-\n-\t/*\n-\t * Since lockfile.c keeps a linked list of all created\n-\t * lock_file structures, it isn't safe to free(lock_file).\n-\t */\n-\tstruct lock_file *lock_file;\n-\tint newfd;\n-\n-\tint apply;\n-\tint allow_overlap;\n-\tint apply_in_reverse;\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/* --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-\tint summary;\n-\tint threeway;\n-\tint no_add;\n-\tconst char *fake_ancestor;\n-\tconst char *patch_input_file;\n-\tstruct string_list limit_by_name;\n-\tint has_include;\n-\tstruct strbuf root;\n-\tstruct string_list symlink_changes;\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-\n-\t/* --index updates the cache as well. */\n-\tint check_index;\n-\n-\tint unidiff_zero;\n-\tint update_index;\n-\tint unsafe_paths;\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-\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-\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-\n-\tconst char *whitespace_option;\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-\tenum ws_ignore ws_ignore_action;\n-};\n+#include \"apply.h\"\n \n static const char * const apply_usage[] = {\n \tN_(\"git apply [<options>] [<patch>...]\"),\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286209","messageId":"20160511131745.2914-58-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 57/94] builtin/apply: make parse_whitespace_option() return -1 instead of die()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:08Z","receivedAt":"2016-05-11T13:17:08Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin builtin/apply.c, parse_whitespace_option() should return -1 using\nerror() instead of calling die().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 23 ++++++++++++-----------\n 1 file changed, 12 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex e42c8fe..657e986 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -27,34 +27,34 @@ static const char * const apply_usage[] = {\n \tNULL\n };\n \n-static void parse_whitespace_option(struct apply_state *state, const char *option)\n+static int parse_whitespace_option(struct apply_state *state, const char *option)\n {\n \tif (!option) {\n \t\tstate->ws_error_action = warn_on_ws_error;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n \tif (!strcmp(option, \"warn\")) {\n \t\tstate->ws_error_action = warn_on_ws_error;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n \tif (!strcmp(option, \"nowarn\")) {\n \t\tstate->ws_error_action = nowarn_ws_error;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n \tif (!strcmp(option, \"error\")) {\n \t\tstate->ws_error_action = die_on_ws_error;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n \tif (!strcmp(option, \"error-all\")) {\n \t\tstate->ws_error_action = die_on_ws_error;\n \t\tstate->squelch_whitespace_errors = 0;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n \tif (!strcmp(option, \"strip\") || !strcmp(option, \"fix\")) {\n \t\tstate->ws_error_action = correct_ws_error;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n-\tdie(_(\"unrecognized whitespace option '%s'\"), option);\n+\treturn error(_(\"unrecognized whitespace option '%s'\"), option);\n }\n \n static void parse_ignorewhitespace_option(struct apply_state *state,\n@@ -4578,7 +4578,8 @@ static int option_parse_whitespace(const struct option *opt,\n {\n \tstruct apply_state *state = opt->value;\n \tstate->whitespace_option = arg;\n-\tparse_whitespace_option(state, arg);\n+\tif (parse_whitespace_option(state, arg))\n+\t\texit(1);\n \treturn 0;\n }\n \n@@ -4612,8 +4613,8 @@ static void init_apply_state(struct apply_state *state,\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_whitespace && parse_whitespace_option(state, apply_default_whitespace))\n+\t\texit(1);\n \tif (apply_default_ignorewhitespace)\n \t\tparse_ignorewhitespace_option(state, apply_default_ignorewhitespace);\n }\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286204","messageId":"20160511131745.2914-59-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 58/94] builtin/apply: make parse_ignorewhitespace_option() return -1 instead of die()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:09Z","receivedAt":"2016-05-11T13:17:09Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", parse_ignorewhitespace_option() should return\n-1 using error() instead of calling die().\n\nSigned-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 657e986..a7ebbbb 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -57,20 +57,20 @@ static int parse_whitespace_option(struct apply_state *state, const char *option\n \treturn error(_(\"unrecognized whitespace option '%s'\"), option);\n }\n \n-static void parse_ignorewhitespace_option(struct apply_state *state,\n-\t\t\t\t\t  const char *option)\n+static int 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\tstate->ws_ignore_action = ignore_ws_none;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n \tif (!strcmp(option, \"change\")) {\n \t\tstate->ws_ignore_action = ignore_ws_change;\n-\t\treturn;\n+\t\treturn 0;\n \t}\n-\tdie(_(\"unrecognized whitespace ignore option '%s'\"), option);\n+\treturn error(_(\"unrecognized whitespace ignore option '%s'\"), option);\n }\n \n static void set_default_whitespace_mode(struct apply_state *state)\n@@ -4615,8 +4615,8 @@ static void init_apply_state(struct apply_state *state,\n \tgit_apply_config();\n \tif (apply_default_whitespace && parse_whitespace_option(state, apply_default_whitespace))\n \t\texit(1);\n-\tif (apply_default_ignorewhitespace)\n-\t\tparse_ignorewhitespace_option(state, apply_default_ignorewhitespace);\n+\tif (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))\n+\t\texit(1);\n }\n \n static void check_apply_state(struct apply_state *state, int force_apply)\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286210","messageId":"20160511131745.2914-60-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 59/94] builtin/apply: move init_apply_state() to apply.c","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:10Z","receivedAt":"2016-05-11T13:17:10Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we must make init_apply_state()\nusable outside \"builtin/apply.c\".\n\nLet's do that by moving it into a new \"apply.c\".\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n Makefile        |  1 +\n apply.c         | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n apply.h         |  9 +++++++\n builtin/apply.c | 79 ------------------------------------------------------\n 4 files changed, 93 insertions(+), 79 deletions(-)\n create mode 100644 apply.c\n\ndiff --git a/Makefile b/Makefile\nindex 3f03366..b2a7b0c 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -683,6 +683,7 @@ LIB_OBJS += abspath.o\n LIB_OBJS += advice.o\n LIB_OBJS += alias.o\n LIB_OBJS += alloc.o\n+LIB_OBJS += apply.o\n LIB_OBJS += archive.o\n LIB_OBJS += archive-tar.o\n LIB_OBJS += archive-zip.o\ndiff --git a/apply.c b/apply.c\nnew file mode 100644\nindex 0000000..508ea64\n--- /dev/null\n+++ b/apply.c\n@@ -0,0 +1,83 @@\n+#include \"cache.h\"\n+#include \"lockfile.h\"\n+#include \"apply.h\"\n+\n+static void git_apply_config(void)\n+{\n+\tgit_config_get_string_const(\"apply.whitespace\", &apply_default_whitespace);\n+\tgit_config_get_string_const(\"apply.ignorewhitespace\", &apply_default_ignorewhitespace);\n+\tgit_config(git_default_config, NULL);\n+}\n+\n+int parse_whitespace_option(struct apply_state *state, const char *option)\n+{\n+\tif (!option) {\n+\t\tstate->ws_error_action = warn_on_ws_error;\n+\t\treturn 0;\n+\t}\n+\tif (!strcmp(option, \"warn\")) {\n+\t\tstate->ws_error_action = warn_on_ws_error;\n+\t\treturn 0;\n+\t}\n+\tif (!strcmp(option, \"nowarn\")) {\n+\t\tstate->ws_error_action = nowarn_ws_error;\n+\t\treturn 0;\n+\t}\n+\tif (!strcmp(option, \"error\")) {\n+\t\tstate->ws_error_action = die_on_ws_error;\n+\t\treturn 0;\n+\t}\n+\tif (!strcmp(option, \"error-all\")) {\n+\t\tstate->ws_error_action = die_on_ws_error;\n+\t\tstate->squelch_whitespace_errors = 0;\n+\t\treturn 0;\n+\t}\n+\tif (!strcmp(option, \"strip\") || !strcmp(option, \"fix\")) {\n+\t\tstate->ws_error_action = correct_ws_error;\n+\t\treturn 0;\n+\t}\n+\treturn error(_(\"unrecognized whitespace option '%s'\"), option);\n+}\n+\n+int parse_ignorewhitespace_option(struct apply_state *state,\n+\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\tstate->ws_ignore_action = ignore_ws_none;\n+\t\treturn 0;\n+\t}\n+\tif (!strcmp(option, \"change\")) {\n+\t\tstate->ws_ignore_action = ignore_ws_change;\n+\t\treturn 0;\n+\t}\n+\treturn error(_(\"unrecognized whitespace ignore option '%s'\"), option);\n+}\n+\n+void init_apply_state(struct apply_state *state,\n+\t\t      const char *prefix,\n+\t\t      struct lock_file *lock_file)\n+{\n+\tmemset(state, 0, sizeof(*state));\n+\tstate->prefix = prefix;\n+\tstate->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n+\tstate->lock_file = lock_file ? lock_file : xcalloc(1, sizeof(*lock_file));\n+\tstate->newfd = -1;\n+\tstate->apply = 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 && parse_whitespace_option(state, apply_default_whitespace))\n+\t\texit(1);\n+\tif (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))\n+\t\texit(1);\n+}\n+\ndiff --git a/apply.h b/apply.h\nindex aa11ea6..0f77f4d 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -112,4 +112,13 @@ struct apply_state {\n \tenum ws_ignore ws_ignore_action;\n };\n \n+extern int parse_whitespace_option(struct apply_state *state,\n+\t\t\t\t   const char *option);\n+extern int parse_ignorewhitespace_option(struct apply_state *state,\n+\t\t\t\t\t const char *option);\n+\n+extern void init_apply_state(struct apply_state *state,\n+\t\t\t     const char *prefix,\n+\t\t\t     struct lock_file *lock_file);\n+\n #endif\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex a7ebbbb..805c707 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -27,52 +27,6 @@ static const char * const apply_usage[] = {\n \tNULL\n };\n \n-static int parse_whitespace_option(struct apply_state *state, const char *option)\n-{\n-\tif (!option) {\n-\t\tstate->ws_error_action = warn_on_ws_error;\n-\t\treturn 0;\n-\t}\n-\tif (!strcmp(option, \"warn\")) {\n-\t\tstate->ws_error_action = warn_on_ws_error;\n-\t\treturn 0;\n-\t}\n-\tif (!strcmp(option, \"nowarn\")) {\n-\t\tstate->ws_error_action = nowarn_ws_error;\n-\t\treturn 0;\n-\t}\n-\tif (!strcmp(option, \"error\")) {\n-\t\tstate->ws_error_action = die_on_ws_error;\n-\t\treturn 0;\n-\t}\n-\tif (!strcmp(option, \"error-all\")) {\n-\t\tstate->ws_error_action = die_on_ws_error;\n-\t\tstate->squelch_whitespace_errors = 0;\n-\t\treturn 0;\n-\t}\n-\tif (!strcmp(option, \"strip\") || !strcmp(option, \"fix\")) {\n-\t\tstate->ws_error_action = correct_ws_error;\n-\t\treturn 0;\n-\t}\n-\treturn error(_(\"unrecognized whitespace option '%s'\"), option);\n-}\n-\n-static int 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\tstate->ws_ignore_action = ignore_ws_none;\n-\t\treturn 0;\n-\t}\n-\tif (!strcmp(option, \"change\")) {\n-\t\tstate->ws_ignore_action = ignore_ws_change;\n-\t\treturn 0;\n-\t}\n-\treturn error(_(\"unrecognized whitespace ignore option '%s'\"), option);\n-}\n-\n static void set_default_whitespace_mode(struct apply_state *state)\n {\n \tif (!state->whitespace_option && !apply_default_whitespace)\n@@ -4528,13 +4482,6 @@ end:\n \treturn res;\n }\n \n-static void git_apply_config(void)\n-{\n-\tgit_config_get_string_const(\"apply.whitespace\", &apply_default_whitespace);\n-\tgit_config_get_string_const(\"apply.ignorewhitespace\", &apply_default_ignorewhitespace);\n-\tgit_config(git_default_config, NULL);\n-}\n-\n static int option_parse_exclude(const struct option *opt,\n \t\t\t\tconst char *arg, int unset)\n {\n@@ -4593,32 +4540,6 @@ static int option_parse_directory(const struct option *opt,\n \treturn 0;\n }\n \n-static void init_apply_state(struct apply_state *state,\n-\t\t\t     const char *prefix,\n-\t\t\t     struct lock_file *lock_file)\n-{\n-\tmemset(state, 0, sizeof(*state));\n-\tstate->prefix = prefix;\n-\tstate->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n-\tstate->lock_file = lock_file ? lock_file : xcalloc(1, sizeof(*lock_file));\n-\tstate->newfd = -1;\n-\tstate->apply = 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 && parse_whitespace_option(state, apply_default_whitespace))\n-\t\texit(1);\n-\tif (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))\n-\t\texit(1);\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-- \n2.8.2.490.g3dabe57\n"},{"id":"286203","messageId":"20160511131745.2914-61-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 60/94] apply: make init_apply_state() return -1 instead of exit()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:11Z","receivedAt":"2016-05-11T13:17:11Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of exit()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", init_apply_state() should return -1 using\nerror() instead of calling exit().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.c         | 11 ++++++-----\n apply.h         |  6 +++---\n builtin/apply.c |  3 ++-\n 3 files changed, 11 insertions(+), 9 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 508ea64..1e2b802 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -55,9 +55,9 @@ int parse_ignorewhitespace_option(struct apply_state *state,\n \treturn error(_(\"unrecognized whitespace ignore option '%s'\"), option);\n }\n \n-void init_apply_state(struct apply_state *state,\n-\t\t      const char *prefix,\n-\t\t      struct lock_file *lock_file)\n+int init_apply_state(struct apply_state *state,\n+\t\t     const char *prefix,\n+\t\t     struct lock_file *lock_file)\n {\n \tmemset(state, 0, sizeof(*state));\n \tstate->prefix = prefix;\n@@ -76,8 +76,9 @@ void init_apply_state(struct apply_state *state,\n \n \tgit_apply_config();\n \tif (apply_default_whitespace && parse_whitespace_option(state, apply_default_whitespace))\n-\t\texit(1);\n+\t\treturn -1;\n \tif (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))\n-\t\texit(1);\n+\t\treturn -1;\n+\treturn 0;\n }\n \ndiff --git a/apply.h b/apply.h\nindex 0f77f4d..f3b2ae4 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -117,8 +117,8 @@ extern int parse_whitespace_option(struct apply_state *state,\n extern int parse_ignorewhitespace_option(struct apply_state *state,\n \t\t\t\t\t const char *option);\n \n-extern void init_apply_state(struct apply_state *state,\n-\t\t\t     const char *prefix,\n-\t\t\t     struct lock_file *lock_file);\n+extern int init_apply_state(struct apply_state *state,\n+\t\t\t    const char *prefix,\n+\t\t\t    struct lock_file *lock_file);\n \n #endif\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 805c707..b31f9eb 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4724,7 +4724,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n-\tinit_apply_state(&state, prefix, NULL);\n+\tif (init_apply_state(&state, prefix, NULL))\n+\t\texit(1);\n \n \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n \t\t\tapply_usage, 0);\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286237","messageId":"20160511131745.2914-62-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 61/94] builtin/apply: make check_apply_state() return -1 instead of die()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:12Z","receivedAt":"2016-05-11T13:17:12Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", check_apply_state() should return -1 using\nerror() instead of calling die().\n\nSigned-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 b31f9eb..2b3d10b 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4540,17 +4540,17 @@ static int option_parse_directory(const struct option *opt,\n \treturn 0;\n }\n \n-static void check_apply_state(struct apply_state *state, int force_apply)\n+static int 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+\t\treturn error(\"--reject and --3way cannot be used together.\");\n \tif (state->cached && state->threeway)\n-\t\tdie(\"--cached and --3way cannot be used together.\");\n+\t\treturn error(\"--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\t\treturn error(_(\"--3way outside a repository\"));\n \t\tstate->check_index = 1;\n \t}\n \tif (state->apply_with_reject)\n@@ -4558,14 +4558,15 @@ static void check_apply_state(struct apply_state *state, int force_apply)\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+\t\treturn error(_(\"--index outside a repository\"));\n \tif (state->cached) {\n \t\tif (is_not_gitdir)\n-\t\t\tdie(_(\"--cached outside a repository\"));\n+\t\t\treturn error(_(\"--cached outside a repository\"));\n \t\tstate->check_index = 1;\n \t}\n \tif (state->check_index)\n \t\tstate->unsafe_paths = 0;\n+\treturn 0;\n }\n \n static int apply_all_patches(struct apply_state *state,\n@@ -4730,7 +4731,8 @@ 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-\tcheck_apply_state(&state, force_apply);\n+\tif (check_apply_state(&state, force_apply))\n+\t\texit(1);\n \n \treturn apply_all_patches(&state, argc, argv, options);\n }\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286205","messageId":"20160511131745.2914-63-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 62/94] builtin/apply: move check_apply_state() to apply.c","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:13Z","receivedAt":"2016-05-11T13:17:13Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we must make check_apply_state()\nusable outside \"builtin/apply.c\".\n\nLet's do that by moving it into \"apply.c\".\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.c         | 29 +++++++++++++++++++++++++++++\n apply.h         |  1 +\n builtin/apply.c | 29 -----------------------------\n 3 files changed, 30 insertions(+), 29 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 1e2b802..2128594 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -82,3 +82,32 @@ int init_apply_state(struct apply_state *state,\n \treturn 0;\n }\n \n+int 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\treturn error(\"--reject and --3way cannot be used together.\");\n+\tif (state->cached && state->threeway)\n+\t\treturn error(\"--cached and --3way cannot be used together.\");\n+\tif (state->threeway) {\n+\t\tif (is_not_gitdir)\n+\t\t\treturn error(_(\"--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\treturn error(_(\"--index outside a repository\"));\n+\tif (state->cached) {\n+\t\tif (is_not_gitdir)\n+\t\t\treturn error(_(\"--cached outside a repository\"));\n+\t\tstate->check_index = 1;\n+\t}\n+\tif (state->check_index)\n+\t\tstate->unsafe_paths = 0;\n+\treturn 0;\n+}\n+\ndiff --git a/apply.h b/apply.h\nindex f3b2ae4..5266612 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -120,5 +120,6 @@ extern int parse_ignorewhitespace_option(struct apply_state *state,\n extern int init_apply_state(struct apply_state *state,\n \t\t\t    const char *prefix,\n \t\t\t    struct lock_file *lock_file);\n+extern int check_apply_state(struct apply_state *state, int force_apply);\n \n #endif\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 2b3d10b..ae16f99 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4540,35 +4540,6 @@ static int option_parse_directory(const struct option *opt,\n \treturn 0;\n }\n \n-static int 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\treturn error(\"--reject and --3way cannot be used together.\");\n-\tif (state->cached && state->threeway)\n-\t\treturn error(\"--cached and --3way cannot be used together.\");\n-\tif (state->threeway) {\n-\t\tif (is_not_gitdir)\n-\t\t\treturn error(_(\"--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\treturn error(_(\"--index outside a repository\"));\n-\tif (state->cached) {\n-\t\tif (is_not_gitdir)\n-\t\t\treturn error(_(\"--cached outside a repository\"));\n-\t\tstate->check_index = 1;\n-\t}\n-\tif (state->check_index)\n-\t\tstate->unsafe_paths = 0;\n-\treturn 0;\n-}\n-\n static int apply_all_patches(struct apply_state *state,\n \t\t\t     int argc,\n \t\t\t     const char **argv,\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286208","messageId":"20160511131745.2914-64-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 63/94] builtin/apply: make apply_all_patches() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:14Z","receivedAt":"2016-05-11T13:17:14Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To finish libifying the apply functionality, apply_all_patches() should not\ndie() or exit() in case of error, but return -1.\n\nWhile doing that we must take care that file descriptors are properly closed\nand, if needed, reset a sensible value.\n\nHelped-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nHelped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 25 +++++++++++++------------\n 1 file changed, 13 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex ae16f99..dd212c9 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4557,7 +4557,7 @@ static int apply_all_patches(struct apply_state *state,\n \t\tif (!strcmp(arg, \"-\")) {\n \t\t\tres = apply_patch(state, 0, \"<stdin>\", options);\n \t\t\tif (res < 0)\n-\t\t\t\texit(1);\n+\t\t\t\treturn -1;\n \t\t\terrs |= res;\n \t\t\tread_stdin = 0;\n \t\t\tcontinue;\n@@ -4568,20 +4568,20 @@ static int apply_all_patches(struct apply_state *state,\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\t\treturn error(_(\"can't open patch '%s': %s\"), arg, strerror(errno));\n \t\tread_stdin = 0;\n \t\tset_default_whitespace_mode(state);\n \t\tres = apply_patch(state, fd, arg, options);\n+\t\tclose(fd);\n \t\tif (res < 0)\n-\t\t\texit(1);\n+\t\t\treturn -1;\n \t\terrs |= res;\n-\t\tclose(fd);\n \t}\n \tset_default_whitespace_mode(state);\n \tif (read_stdin) {\n \t\tres = apply_patch(state, 0, \"<stdin>\", options);\n \t\tif (res < 0)\n-\t\t\texit(1);\n+\t\t\treturn -1;\n \t\terrs |= res;\n \t}\n \n@@ -4596,10 +4596,10 @@ static int apply_all_patches(struct apply_state *state,\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\t\treturn error(Q_(\"%d line adds whitespace errors.\",\n+\t\t\t\t\t\"%d lines add whitespace errors.\",\n+\t\t\t\t\tstate->whitespace_error),\n+\t\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@@ -4613,9 +4613,10 @@ static int apply_all_patches(struct apply_state *state,\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\tres = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);\n \t\tstate->newfd = -1;\n+\t\tif (res)\n+\t\t\treturn error(_(\"Unable to write new index file\"));\n \t}\n \n \treturn !!errs;\n@@ -4705,5 +4706,5 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\n \tif (check_apply_state(&state, force_apply))\n \t\texit(1);\n \n-\treturn apply_all_patches(&state, argc, argv, options);\n+\treturn !!apply_all_patches(&state, argc, argv, options);\n }\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286207","messageId":"20160511131745.2914-65-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 64/94] builtin/apply: make parse_traditional_patch() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:15Z","receivedAt":"2016-05-11T13:17:15Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", parse_traditional_patch() should return -1 using\nerror() instead of calling die().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 15 +++++++++------\n 1 file changed, 9 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex dd212c9..8e82eea 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -755,10 +755,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(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+static int 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@@ -803,7 +803,9 @@ 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\"), state->linenr);\n+\t\treturn error(_(\"unable to find filename in patch at line %d\"), state->linenr);\n+\n+\treturn 0;\n }\n \n static int gitdiff_hdrend(struct apply_state *state,\n@@ -1462,7 +1464,8 @@ static int find_header(struct apply_state *state,\n \t\t\tcontinue;\n \n \t\t/* Ok, we'll consider it a patch */\n-\t\tparse_traditional_patch(state, line, line+len, patch);\n+\t\tif (parse_traditional_patch(state, line, line+len, patch))\n+\t\t\treturn -1;\n \t\t*hdrsize = len + nextlen;\n \t\tstate->linenr += 2;\n \t\treturn offset;\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286239","messageId":"20160511131745.2914-66-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 65/94] builtin/apply: make gitdiff_*() return 1 at end of header","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:16Z","receivedAt":"2016-05-11T13:17:16Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"The gitdiff_*() functions that are called as p->fn() in parse_git_header()\nshould return 1 instead of -1 in case of end of header or unrecognized\ninput, as these are not real errors. It just instructs the parser to break\nout.\n\nThis makes it possible for gitdiff_*() functions to return -1 in case of a\nreal error. This will be done in a following patch.\n\nHelped-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 12 +++++++++---\n 1 file changed, 9 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 8e82eea..b3a9c2e 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -812,7 +812,7 @@ 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+\treturn 1;\n }\n \n /*\n@@ -1016,7 +1016,7 @@ 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+\treturn 1;\n }\n \n /*\n@@ -1248,9 +1248,13 @@ static int parse_git_header(struct apply_state *state,\n \t\tfor (i = 0; i < ARRAY_SIZE(optable); i++) {\n \t\t\tconst struct opentry *p = optable + i;\n \t\t\tint oplen = strlen(p->str);\n+\t\t\tint res;\n \t\t\tif (len < oplen || memcmp(p->str, line, oplen))\n \t\t\t\tcontinue;\n-\t\t\tif (p->fn(state, line + oplen, patch) < 0)\n+\t\t\tres = p->fn(state, line + oplen, patch);\n+\t\t\tif (res < 0)\n+\t\t\t\treturn -1;\n+\t\t\tif (res > 0)\n \t\t\t\treturn offset;\n \t\t\tbreak;\n \t\t}\n@@ -1429,6 +1433,8 @@ static int find_header(struct apply_state *state,\n \t\t */\n \t\tif (!memcmp(\"diff --git \", line, 11)) {\n \t\t\tint git_hdr_len = parse_git_header(state, line, len, size, patch);\n+\t\t\tif (git_hdr_len < 0)\n+\t\t\t\treturn -1;\n \t\t\tif (git_hdr_len <= len)\n \t\t\t\tcontinue;\n \t\t\tif (!patch->old_name && !patch->new_name) {\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286238","messageId":"20160511131745.2914-67-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 66/94] builtin/apply: make gitdiff_*() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:17Z","receivedAt":"2016-05-11T13:17:17Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", gitdiff_*() functions should return -1 using\nerror() instead of calling die().\n\nA previous patch made it possible for gitdiff_*() functions to\nreturn -1 in case of error. Let's take advantage of that to\nmake gitdiff_verify_name() return -1 on error, and to have\ngitdiff_oldname() and gitdiff_newname() directly return\nwhat gitdiff_verify_name() returns.\n\nHelped-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 40 +++++++++++++++++++++-------------------\n 1 file changed, 21 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex b3a9c2e..42b0a24 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -827,54 +827,56 @@ static int gitdiff_hdrend(struct apply_state *state,\n #define DIFF_OLD_NAME 0\n #define DIFF_NEW_NAME 1\n \n-static void gitdiff_verify_name(struct apply_state *state,\n-\t\t\t\tconst char *line,\n-\t\t\t\tint isnull,\n-\t\t\t\tchar **name,\n-\t\t\t\tint side)\n+static int gitdiff_verify_name(struct apply_state *state,\n+\t\t\t       const char *line,\n+\t\t\t       int isnull,\n+\t\t\t       char **name,\n+\t\t\t       int side)\n {\n \tif (!*name && !isnull) {\n \t\t*name = find_name(state, line, NULL, state->p_value, TERM_TAB);\n-\t\treturn;\n+\t\treturn 0;\n \t}\n \n \tif (*name) {\n \t\tint len = strlen(*name);\n \t\tchar *another;\n \t\tif (isnull)\n-\t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n-\t\t\t    *name, state->linenr);\n+\t\t\treturn error(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n+\t\t\t\t     *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\tif (!another || memcmp(another, *name, len + 1)) {\n+\t\t\tfree(another);\n+\t\t\treturn error((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\"), state->linenr);\n+\t\t}\n \t\tfree(another);\n \t} else {\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\"), state->linenr);\n+\t\t\treturn error(_(\"git apply: bad git-diff - expected /dev/null on line %d\"), state->linenr);\n \t}\n+\n+\treturn 0;\n }\n \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-\tgitdiff_verify_name(state, line,\n-\t\t\t    patch->is_new, &patch->old_name,\n-\t\t\t    DIFF_OLD_NAME);\n-\treturn 0;\n+\treturn gitdiff_verify_name(state, line,\n+\t\t\t\t   patch->is_new, &patch->old_name,\n+\t\t\t\t   DIFF_OLD_NAME);\n }\n \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-\tgitdiff_verify_name(state, line,\n-\t\t\t    patch->is_delete, &patch->new_name,\n-\t\t\t    DIFF_NEW_NAME);\n-\treturn 0;\n+\treturn gitdiff_verify_name(state, line,\n+\t\t\t\t   patch->is_delete, &patch->new_name,\n+\t\t\t\t   DIFF_NEW_NAME);\n }\n \n static int gitdiff_oldmode(struct apply_state *state,\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286240","messageId":"20160511131745.2914-68-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 67/94] builtin/apply: change die_on_unsafe_path() to check_unsafe_path()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:18Z","receivedAt":"2016-05-11T13:17:18Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", die_on_unsafe_path() should return -1 using\nerror() instead of calling die(), so while doing that let's change\nits name to check_unsafe_path().\n\nSigned-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 42b0a24..06c1c16 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -3698,7 +3698,7 @@ static int path_is_beyond_symlink(struct apply_state *state, const char *name_)\n \treturn ret;\n }\n \n-static void die_on_unsafe_path(struct patch *patch)\n+static int check_unsafe_path(struct patch *patch)\n {\n \tconst char *old_name = NULL;\n \tconst char *new_name = NULL;\n@@ -3710,9 +3710,10 @@ static void die_on_unsafe_path(struct patch *patch)\n \t\tnew_name = patch->new_name;\n \n \tif (old_name && !verify_path(old_name))\n-\t\tdie(_(\"invalid path '%s'\"), old_name);\n+\t\treturn error(_(\"invalid path '%s'\"), old_name);\n \tif (new_name && !verify_path(new_name))\n-\t\tdie(_(\"invalid path '%s'\"), new_name);\n+\t\treturn error(_(\"invalid path '%s'\"), new_name);\n+\treturn 0;\n }\n \n /*\n@@ -3802,8 +3803,8 @@ static int check_patch(struct apply_state *state, struct patch *patch)\n \t\t}\n \t}\n \n-\tif (!state->unsafe_paths)\n-\t\tdie_on_unsafe_path(patch);\n+\tif (!state->unsafe_paths && check_unsafe_path(patch))\n+\t\treturn -1;\n \n \t/*\n \t * An attempt to read from or delete a path that is beyond a\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286241","messageId":"20160511131745.2914-69-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 68/94] builtin/apply: make build_fake_ancestor() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:19Z","receivedAt":"2016-05-11T13:17:19Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", build_fake_ancestor() should return -1 using\nerror() instead of calling die().\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 41 ++++++++++++++++++++++++++---------------\n 1 file changed, 26 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 06c1c16..a2cc099 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -3890,11 +3890,12 @@ static int preimage_sha1_in_gitlink_patch(struct patch *p, unsigned char sha1[20\n }\n \n /* Build an index that contains the just the files needed for a 3way merge */\n-static void build_fake_ancestor(struct patch *list, const char *filename)\n+static int build_fake_ancestor(struct patch *list, const char *filename)\n {\n \tstruct patch *patch;\n \tstruct index_state result = { NULL };\n \tstatic struct lock_file lock;\n+\tint res;\n \n \t/* Once we start supporting the reverse patch, it may be\n \t * worth showing the new sha1 prefix, but until then...\n@@ -3912,31 +3913,38 @@ static void build_fake_ancestor(struct patch *list, const char *filename)\n \t\t\tif (!preimage_sha1_in_gitlink_patch(patch, sha1))\n \t\t\t\t; /* ok, the textual part looks sane */\n \t\t\telse\n-\t\t\t\tdie(\"sha1 information is lacking or useless for submodule %s\",\n-\t\t\t\t    name);\n+\t\t\t\treturn error(\"sha1 information is lacking or \"\n+\t\t\t\t\t     \"useless for submodule %s\", name);\n \t\t} else if (!get_sha1_blob(patch->old_sha1_prefix, sha1)) {\n \t\t\t; /* ok */\n \t\t} else if (!patch->lines_added && !patch->lines_deleted) {\n \t\t\t/* mode-only change: update the current */\n \t\t\tif (get_current_sha1(patch->old_name, sha1))\n-\t\t\t\tdie(\"mode change for %s, which is not \"\n-\t\t\t\t    \"in current HEAD\", name);\n+\t\t\t\treturn error(\"mode change for %s, which is not \"\n+\t\t\t\t\t     \"in current HEAD\", name);\n \t\t} else\n-\t\t\tdie(\"sha1 information is lacking or useless \"\n-\t\t\t    \"(%s).\", name);\n+\t\t\treturn error(\"sha1 information is lacking or useless \"\n+\t\t\t\t     \"(%s).\", name);\n \n \t\tce = make_cache_entry(patch->old_mode, sha1, name, 0, 0);\n \t\tif (!ce)\n-\t\t\tdie(_(\"make_cache_entry failed for path '%s'\"), name);\n-\t\tif (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD))\n-\t\t\tdie (\"Could not add %s to temporary index\", name);\n+\t\t\treturn error(_(\"make_cache_entry failed for path '%s'\"),\n+\t\t\t\t     name);\n+\t\tif (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD)) {\n+\t\t\tfree(ce);\n+\t\t\treturn error(\"Could not add %s to temporary index\",\n+\t\t\t\t     name);\n+\t\t}\n \t}\n \n \thold_lock_file_for_update(&lock, filename, LOCK_DIE_ON_ERROR);\n-\tif (write_locked_index(&result, &lock, COMMIT_LOCK))\n-\t\tdie (\"Could not write temporary index to %s\", filename);\n-\n+\tres = write_locked_index(&result, &lock, COMMIT_LOCK);\n \tdiscard_index(&result);\n+\n+\tif (res)\n+\t\treturn error(\"Could not write temporary index to %s\", filename);\n+\n+\treturn 0;\n }\n \n static void stat_patch_list(struct apply_state *state, struct patch *patch)\n@@ -4475,8 +4483,11 @@ static int apply_patch(struct apply_state *state,\n \t\tgoto end;\n \t}\n \n-\tif (state->fake_ancestor)\n-\t\tbuild_fake_ancestor(list, state->fake_ancestor);\n+\tif (state->fake_ancestor &&\n+\t    build_fake_ancestor(list, state->fake_ancestor)) {\n+\t\tres = -1;\n+\t\tgoto end;\n+\t}\n \n \tif (state->diffstat)\n \t\tstat_patch_list(state, list);\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286214","messageId":"20160511131745.2914-70-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 69/94] builtin/apply: make remove_file() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:20Z","receivedAt":"2016-05-11T13:17:20Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", remove_file() should return -1 using error()\ninstead of calling die().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 17 +++++++++++------\n 1 file changed, 11 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex a2cc099..52f36c2 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4075,17 +4075,18 @@ static void patch_stats(struct apply_state *state, struct patch *patch)\n \t}\n }\n \n-static void remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)\n+static int remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)\n {\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\t\treturn error(_(\"unable to remove %s from index\"), patch->old_name);\n \t}\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 \t}\n+\treturn 0;\n }\n \n static void add_index_file(struct apply_state *state,\n@@ -4264,8 +4265,10 @@ static void write_out_one_result(struct apply_state *state,\n \t\t\t\t int phase)\n {\n \tif (patch->is_delete > 0) {\n-\t\tif (phase == 0)\n-\t\t\tremove_file(state, patch, 1);\n+\t\tif (phase == 0) {\n+\t\t\tif (remove_file(state, patch, 1))\n+\t\t\t\texit(1);\n+\t\t}\n \t\treturn;\n \t}\n \tif (patch->is_new > 0 || patch->is_copy) {\n@@ -4277,8 +4280,10 @@ static void write_out_one_result(struct apply_state *state,\n \t * Rename or modification boils down to the same\n \t * thing: remove the old, write the new\n \t */\n-\tif (phase == 0)\n-\t\tremove_file(state, patch, patch->is_rename);\n+\tif (phase == 0) {\n+\t\tif (remove_file(state, patch, patch->is_rename))\n+\t\t\texit(1);\n+\t}\n \tif (phase == 1)\n \t\tcreate_file(state, patch);\n }\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286236","messageId":"20160511131745.2914-71-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 70/94] builtin/apply: make add_conflicted_stages_file() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:21Z","receivedAt":"2016-05-11T13:17:21Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", add_conflicted_stages_file() should return -1\nusing error() instead of calling die().\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 20 +++++++++++++-------\n 1 file changed, 13 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 52f36c2..ca3502f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4214,7 +4214,7 @@ static void create_one_file(struct apply_state *state,\n \tdie_errno(_(\"unable to write file '%s' mode %o\"), path, mode);\n }\n \n-static void add_conflicted_stages_file(struct apply_state *state,\n+static int add_conflicted_stages_file(struct apply_state *state,\n \t\t\t\t       struct patch *patch)\n {\n \tint stage, namelen;\n@@ -4222,7 +4222,7 @@ static void add_conflicted_stages_file(struct apply_state *state,\n \tstruct cache_entry *ce;\n \n \tif (!state->update_index)\n-\t\treturn;\n+\t\treturn 0;\n \tnamelen = strlen(patch->new_name);\n \tce_size = cache_entry_size(namelen);\n \tmode = patch->new_mode ? patch->new_mode : (S_IFREG | 0644);\n@@ -4237,9 +4237,14 @@ static void add_conflicted_stages_file(struct apply_state *state,\n \t\tce->ce_flags = create_ce_flags(stage);\n \t\tce->ce_namelen = namelen;\n \t\thashcpy(ce->sha1, patch->threeway_stage[stage - 1].hash);\n-\t\tif (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)\n-\t\t\tdie(_(\"unable to add cache entry for %s\"), patch->new_name);\n+\t\tif (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {\n+\t\t\tfree(ce);\n+\t\t\treturn error(_(\"unable to add cache entry for %s\"),\n+\t\t\t\t     patch->new_name);\n+\t\t}\n \t}\n+\n+\treturn 0;\n }\n \n static void create_file(struct apply_state *state, struct patch *patch)\n@@ -4253,9 +4258,10 @@ static void create_file(struct apply_state *state, struct patch *patch)\n \t\tmode = S_IFREG | 0644;\n \tcreate_one_file(state, path, mode, buf, size);\n \n-\tif (patch->conflicted_threeway)\n-\t\tadd_conflicted_stages_file(state, patch);\n-\telse\n+\tif (patch->conflicted_threeway) {\n+\t\tif (add_conflicted_stages_file(state, patch))\n+\t\t\texit(1);\n+\t} else\n \t\tadd_index_file(state, path, mode, buf, size);\n }\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286213","messageId":"20160511131745.2914-72-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 71/94] builtin/apply: make add_index_file() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:22Z","receivedAt":"2016-05-11T13:17:22Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", add_index_file() should return -1 using error()\ninstead of calling die().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 48 +++++++++++++++++++++++++++++++-----------------\n 1 file changed, 31 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex ca3502f..0e20467 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4089,11 +4089,11 @@ static int remove_file(struct apply_state *state, struct patch *patch, int rmdir\n \treturn 0;\n }\n \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+static int 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@@ -4101,7 +4101,7 @@ static void add_index_file(struct apply_state *state,\n \tunsigned ce_size = cache_entry_size(namelen);\n \n \tif (!state->update_index)\n-\t\treturn;\n+\t\treturn 0;\n \n \tce = xcalloc(1, ce_size);\n \tmemcpy(ce->name, path, namelen);\n@@ -4112,20 +4112,32 @@ static void add_index_file(struct apply_state *state,\n \t\tconst char *s;\n \n \t\tif (!skip_prefix(buf, \"Subproject commit \", &s) ||\n-\t\t    get_sha1_hex(s, ce->sha1))\n-\t\t\tdie(_(\"corrupt patch for submodule %s\"), path);\n+\t\t    get_sha1_hex(s, ce->sha1)) {\n+\t\t\tfree(ce);\n+\t\t\treturn error(_(\"corrupt patch for submodule %s\"), path);\n+\t\t}\n \t} else {\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+\t\t\tif (lstat(path, &st) < 0) {\n+\t\t\t\tfree(ce);\n+\t\t\t\treturn error(_(\"unable to stat newly \"\n+\t\t\t\t\t       \"created file '%s': %s\"),\n+\t\t\t\t\t     path, strerror(errno));\n+\t\t\t}\n \t\t\tfill_stat_cache_info(ce, &st);\n \t\t}\n-\t\tif (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)\n-\t\t\tdie(_(\"unable to create backing store for newly created file %s\"), path);\n+\t\tif (write_sha1_file(buf, size, blob_type, ce->sha1) < 0) {\n+\t\t\tfree(ce);\n+\t\t\treturn error(_(\"unable to create backing store \"\n+\t\t\t\t       \"for newly created file %s\"), path);\n+\t\t}\n \t}\n-\tif (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)\n-\t\tdie(_(\"unable to add cache entry for %s\"), path);\n+\tif (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {\n+\t\tfree(ce);\n+\t\treturn error(_(\"unable to add cache entry for %s\"), path);\n+\t}\n+\n+\treturn 0;\n }\n \n static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)\n@@ -4261,8 +4273,10 @@ static void create_file(struct apply_state *state, struct patch *patch)\n \tif (patch->conflicted_threeway) {\n \t\tif (add_conflicted_stages_file(state, patch))\n \t\t\texit(1);\n-\t} else\n-\t\tadd_index_file(state, path, mode, buf, size);\n+\t} else {\n+\t\tif (add_index_file(state, path, mode, buf, size))\n+\t\t\texit(1);\n+\t}\n }\n \n /* phase zero is to remove, phase one is to create */\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286233","messageId":"20160511131745.2914-73-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 72/94] builtin/apply: make create_file() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:23Z","receivedAt":"2016-05-11T13:17:23Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of exit()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", create_file() should just return what\nadd_conflicted_stages_file() and add_index_file() are returning\ninstead of calling exit().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 25 +++++++++++++------------\n 1 file changed, 13 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 0e20467..2b562db 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4259,7 +4259,7 @@ static int add_conflicted_stages_file(struct apply_state *state,\n \treturn 0;\n }\n \n-static void create_file(struct apply_state *state, struct patch *patch)\n+static int create_file(struct apply_state *state, struct patch *patch)\n {\n \tchar *path = patch->new_name;\n \tunsigned mode = patch->new_mode;\n@@ -4270,13 +4270,10 @@ static void create_file(struct apply_state *state, struct patch *patch)\n \t\tmode = S_IFREG | 0644;\n \tcreate_one_file(state, path, mode, buf, size);\n \n-\tif (patch->conflicted_threeway) {\n-\t\tif (add_conflicted_stages_file(state, patch))\n-\t\t\texit(1);\n-\t} else {\n-\t\tif (add_index_file(state, path, mode, buf, size))\n-\t\t\texit(1);\n-\t}\n+\tif (patch->conflicted_threeway)\n+\t\treturn add_conflicted_stages_file(state, patch);\n+\telse\n+\t\treturn add_index_file(state, path, mode, buf, size);\n }\n \n /* phase zero is to remove, phase one is to create */\n@@ -4292,8 +4289,10 @@ static void write_out_one_result(struct apply_state *state,\n \t\treturn;\n \t}\n \tif (patch->is_new > 0 || patch->is_copy) {\n-\t\tif (phase == 1)\n-\t\t\tcreate_file(state, patch);\n+\t\tif (phase == 1) {\n+\t\t\tif (create_file(state, patch))\n+\t\t\t\texit(1);\n+\t\t}\n \t\treturn;\n \t}\n \t/*\n@@ -4304,8 +4303,10 @@ static void write_out_one_result(struct apply_state *state,\n \t\tif (remove_file(state, patch, patch->is_rename))\n \t\t\texit(1);\n \t}\n-\tif (phase == 1)\n-\t\tcreate_file(state, patch);\n+\tif (phase == 1) {\n+\t\tif (create_file(state, patch))\n+\t\t\texit(1);\n+\t}\n }\n \n static int write_out_one_reject(struct apply_state *state, struct patch *patch)\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286235","messageId":"20160511131745.2914-74-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 73/94] builtin/apply: make write_out_one_result() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:24Z","receivedAt":"2016-05-11T13:17:24Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of exit()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", write_out_one_result() should just return what\nremove_file() and create_file() are returning instead of calling\nexit().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 38 ++++++++++++++++----------------------\n 1 file changed, 16 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 2b562db..f06bf16 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4277,36 +4277,29 @@ static int create_file(struct apply_state *state, struct patch *patch)\n }\n \n /* phase zero is to remove, phase one is to create */\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+static int write_out_one_result(struct apply_state *state,\n+\t\t\t\tstruct patch *patch,\n+\t\t\t\tint phase)\n {\n \tif (patch->is_delete > 0) {\n-\t\tif (phase == 0) {\n-\t\t\tif (remove_file(state, patch, 1))\n-\t\t\t\texit(1);\n-\t\t}\n-\t\treturn;\n+\t\tif (phase == 0)\n+\t\t\treturn remove_file(state, patch, 1);\n+\t\treturn 0;\n \t}\n \tif (patch->is_new > 0 || patch->is_copy) {\n-\t\tif (phase == 1) {\n-\t\t\tif (create_file(state, patch))\n-\t\t\t\texit(1);\n-\t\t}\n-\t\treturn;\n+\t\tif (phase == 1)\n+\t\t\treturn create_file(state, patch);\n+\t\treturn 0;\n \t}\n \t/*\n \t * Rename or modification boils down to the same\n \t * thing: remove the old, write the new\n \t */\n-\tif (phase == 0) {\n-\t\tif (remove_file(state, patch, patch->is_rename))\n-\t\t\texit(1);\n-\t}\n-\tif (phase == 1) {\n-\t\tif (create_file(state, patch))\n-\t\t\texit(1);\n-\t}\n+\tif (phase == 0)\n+\t\treturn remove_file(state, patch, patch->is_rename);\n+\tif (phase == 1)\n+\t\treturn create_file(state, patch);\n+\treturn 0;\n }\n \n static int write_out_one_reject(struct apply_state *state, struct patch *patch)\n@@ -4393,7 +4386,8 @@ 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(state, l, phase);\n+\t\t\t\tif (write_out_one_result(state, l, phase))\n+\t\t\t\t\texit(1);\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-- \n2.8.2.490.g3dabe57\n"},{"id":"286218","messageId":"20160511131745.2914-75-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 74/94] builtin/apply: make write_out_results() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:25Z","receivedAt":"2016-05-11T13:17:25Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of exit()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", write_out_results() should return -1 instead of\ncalling exit().\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 27 +++++++++++++++++++++------\n 1 file changed, 21 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex f06bf16..97bc704 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4373,6 +4373,12 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)\n \treturn -1;\n }\n \n+/*\n+ * Returns:\n+ *  -1 if an error happened\n+ *   0 if the patch applied cleanly\n+ *   1 if the patch did not apply cleanly\n+ */\n static int write_out_results(struct apply_state *state, struct patch *list)\n {\n \tint phase;\n@@ -4386,8 +4392,10 @@ 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\tif (write_out_one_result(state, l, phase))\n-\t\t\t\t\texit(1);\n+\t\t\t\tif (write_out_one_result(state, l, phase)) {\n+\t\t\t\t\tstring_list_clear(&cpath, 0);\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\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@@ -4497,10 +4505,17 @@ static int apply_patch(struct apply_state *state,\n \t\tgoto end;\n \t}\n \n-\tif (state->apply && write_out_results(state, list)) {\n-\t\t/* with --3way, we still need to write the index out */\n-\t\tres = state->apply_with_reject ? -1 : 1;\n-\t\tgoto end;\n+\tif (state->apply) {\n+\t\tint write_res = write_out_results(state, list);\n+\t\tif (write_res < 0) {\n+\t\t\tres = -1;\n+\t\t\tgoto end;\n+\t\t}\n+\t\tif (write_res > 0) {\n+\t\t\t/* with --3way, we still need to write the index out */\n+\t\t\tres = state->apply_with_reject ? -1 : 1;\n+\t\t\tgoto end;\n+\t\t}\n \t}\n \n \tif (state->fake_ancestor &&\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286212","messageId":"20160511131745.2914-76-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 75/94] builtin/apply: make try_create_file() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:26Z","receivedAt":"2016-05-11T13:17:26Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of die()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", try_create_file() should return -1 in case of\nerror.\n\nUnfortunately try_create_file() currently returns -1 to signal a\nrecoverable error. To fix that, let's make it return 1 in case of\na recoverable error and -1 in case of an unrecoverable error.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 41 ++++++++++++++++++++++++++++++-----------\n 1 file changed, 30 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 97bc704..eaf7b8f 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4140,38 +4140,45 @@ static int add_index_file(struct apply_state *state,\n \treturn 0;\n }\n \n+/*\n+ * Returns:\n+ *  -1 if an unrecoverable error happened\n+ *   0 if everything went well\n+ *   1 if a recoverable error happened\n+ */\n static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)\n {\n-\tint fd;\n+\tint fd, res;\n \tstruct strbuf nbuf = STRBUF_INIT;\n \n \tif (S_ISGITLINK(mode)) {\n \t\tstruct stat st;\n \t\tif (!lstat(path, &st) && S_ISDIR(st.st_mode))\n \t\t\treturn 0;\n-\t\treturn mkdir(path, 0777);\n+\t\treturn !!mkdir(path, 0777);\n \t}\n \n \tif (has_symlinks && S_ISLNK(mode))\n \t\t/* Although buf:size is counted string, it also is NUL\n \t\t * terminated.\n \t\t */\n-\t\treturn symlink(buf, path);\n+\t\treturn !!symlink(buf, path);\n \n \tfd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);\n \tif (fd < 0)\n-\t\treturn -1;\n+\t\treturn 1;\n \n \tif (convert_to_working_tree(path, buf, size, &nbuf)) {\n \t\tsize = nbuf.len;\n \t\tbuf  = nbuf.buf;\n \t}\n-\twrite_or_die(fd, buf, size);\n+\tres = !write_or_whine_pipe(fd, buf, size, path);\n \tstrbuf_release(&nbuf);\n \n-\tif (close(fd) < 0)\n-\t\tdie_errno(_(\"closing file '%s'\"), path);\n-\treturn 0;\n+\tif (close(fd) < 0 && !res)\n+\t\treturn error(_(\"closing file '%s': %s\"), path, strerror(errno));\n+\n+\treturn res ? -1 : 0;\n }\n \n /*\n@@ -4185,15 +4192,24 @@ static void create_one_file(struct apply_state *state,\n \t\t\t    const char *buf,\n \t\t\t    unsigned long size)\n {\n+\tint res;\n+\n \tif (state->cached)\n \t\treturn;\n-\tif (!try_create_file(path, mode, buf, size))\n+\n+\tres = try_create_file(path, mode, buf, size);\n+\tif (res < 0)\n+\t\texit(1);\n+\tif (!res)\n \t\treturn;\n \n \tif (errno == ENOENT) {\n \t\tif (safe_create_leading_directories(path))\n \t\t\treturn;\n-\t\tif (!try_create_file(path, mode, buf, size))\n+\t\tres = try_create_file(path, mode, buf, size);\n+\t\tif (res < 0)\n+\t\t\texit(1);\n+\t\tif (!res)\n \t\t\treturn;\n \t}\n \n@@ -4212,7 +4228,10 @@ static void create_one_file(struct apply_state *state,\n \t\tfor (;;) {\n \t\t\tchar newpath[PATH_MAX];\n \t\t\tmksnpath(newpath, sizeof(newpath), \"%s~%u\", path, nr);\n-\t\t\tif (!try_create_file(newpath, mode, buf, size)) {\n+\t\t\tres = try_create_file(newpath, mode, buf, size);\n+\t\t\tif (res < 0)\n+\t\t\t\texit(1);\n+\t\t\tif (!res) {\n \t\t\t\tif (!rename(newpath, path))\n \t\t\t\t\treturn;\n \t\t\t\tunlink_or_warn(newpath);\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286216","messageId":"20160511131745.2914-77-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 76/94] builtin/apply: make create_one_file() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:27Z","receivedAt":"2016-05-11T13:17:27Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To libify `git apply` functionality we have to signal errors to the\ncaller instead of exit()ing.\n\nTo do that in a compatible manner with the rest of the error handling\nin \"builtin/apply.c\", create_one_file() should return -1 instead of\ncalling exit().\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 36 +++++++++++++++++++++---------------\n 1 file changed, 21 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex eaf7b8f..8c31617 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4185,32 +4185,36 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,\n  * We optimistically assume that the directories exist,\n  * which is true 99% of the time anyway. If they don't,\n  * we create them and try again.\n+ *\n+ * Returns:\n+ *   -1 on error\n+ *   0 otherwise\n  */\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+static int 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 \tint res;\n \n \tif (state->cached)\n-\t\treturn;\n+\t\treturn 0;\n \n \tres = try_create_file(path, mode, buf, size);\n \tif (res < 0)\n-\t\texit(1);\n+\t\treturn -1;\n \tif (!res)\n-\t\treturn;\n+\t\treturn 0;\n \n \tif (errno == ENOENT) {\n \t\tif (safe_create_leading_directories(path))\n-\t\t\treturn;\n+\t\t\treturn 0;\n \t\tres = try_create_file(path, mode, buf, size);\n \t\tif (res < 0)\n-\t\t\texit(1);\n+\t\t\treturn -1;\n \t\tif (!res)\n-\t\t\treturn;\n+\t\t\treturn 0;\n \t}\n \n \tif (errno == EEXIST || errno == EACCES) {\n@@ -4230,10 +4234,10 @@ static void create_one_file(struct apply_state *state,\n \t\t\tmksnpath(newpath, sizeof(newpath), \"%s~%u\", path, nr);\n \t\t\tres = try_create_file(newpath, mode, buf, size);\n \t\t\tif (res < 0)\n-\t\t\t\texit(1);\n+\t\t\t\treturn -1;\n \t\t\tif (!res) {\n \t\t\t\tif (!rename(newpath, path))\n-\t\t\t\t\treturn;\n+\t\t\t\t\treturn 0;\n \t\t\t\tunlink_or_warn(newpath);\n \t\t\t\tbreak;\n \t\t\t}\n@@ -4242,7 +4246,8 @@ static void create_one_file(struct apply_state *state,\n \t\t\t++nr;\n \t\t}\n \t}\n-\tdie_errno(_(\"unable to write file '%s' mode %o\"), path, mode);\n+\treturn error(_(\"unable to write file '%s' mode %o: %s\"),\n+\t\t     path, mode, strerror(errno));\n }\n \n static int add_conflicted_stages_file(struct apply_state *state,\n@@ -4287,7 +4292,8 @@ static int create_file(struct apply_state *state, struct patch *patch)\n \n \tif (!mode)\n \t\tmode = S_IFREG | 0644;\n-\tcreate_one_file(state, path, mode, buf, size);\n+\tif (create_one_file(state, path, mode, buf, size))\n+\t\treturn -1;\n \n \tif (patch->conflicted_threeway)\n \t\treturn add_conflicted_stages_file(state, patch);\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286234","messageId":"20160511131745.2914-78-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 77/94] builtin/apply: rename option parsing functions","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:28Z","receivedAt":"2016-05-11T13:17:28Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"As these functions are going to be part of the libified\napply api, let's give them a name that is more specific\nto the apply api.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 40 ++++++++++++++++++++--------------------\n 1 file changed, 20 insertions(+), 20 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 8c31617..f05dc96 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4565,16 +4565,16 @@ end:\n \treturn res;\n }\n \n-static int option_parse_exclude(const struct option *opt,\n-\t\t\t\tconst char *arg, int unset)\n+static int apply_option_parse_exclude(const struct option *opt,\n+\t\t\t\t      const char *arg, int unset)\n {\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+static int apply_option_parse_include(const struct option *opt,\n+\t\t\t\t      const char *arg, int unset)\n {\n \tstruct apply_state *state = opt->value;\n \tadd_name_limit(state, arg, 0);\n@@ -4582,9 +4582,9 @@ static int option_parse_include(const struct option *opt,\n \treturn 0;\n }\n \n-static int option_parse_p(const struct option *opt,\n-\t\t\t  const char *arg,\n-\t\t\t  int unset)\n+static int apply_option_parse_p(const struct option *opt,\n+\t\t\t\tconst char *arg,\n+\t\t\t\tint unset)\n {\n \tstruct apply_state *state = opt->value;\n \tstate->p_value = atoi(arg);\n@@ -4592,8 +4592,8 @@ static int option_parse_p(const struct option *opt,\n \treturn 0;\n }\n \n-static int option_parse_space_change(const struct option *opt,\n-\t\t\t\t     const char *arg, int unset)\n+static int apply_option_parse_space_change(const struct option *opt,\n+\t\t\t\t\t   const char *arg, int unset)\n {\n \tstruct apply_state *state = opt->value;\n \tif (unset)\n@@ -4603,8 +4603,8 @@ static int option_parse_space_change(const struct option *opt,\n \treturn 0;\n }\n \n-static int option_parse_whitespace(const struct option *opt,\n-\t\t\t\t   const char *arg, int unset)\n+static int apply_option_parse_whitespace(const struct option *opt,\n+\t\t\t\t\t const char *arg, int unset)\n {\n \tstruct apply_state *state = opt->value;\n \tstate->whitespace_option = arg;\n@@ -4613,8 +4613,8 @@ static int option_parse_whitespace(const struct option *opt,\n \treturn 0;\n }\n \n-static int option_parse_directory(const struct option *opt,\n-\t\t\t\t  const char *arg, int unset)\n+static int apply_option_parse_directory(const struct option *opt,\n+\t\t\t\t\tconst char *arg, int unset)\n {\n \tstruct apply_state *state = opt->value;\n \tstrbuf_reset(&state->root);\n@@ -4714,13 +4714,13 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\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-\t\t\t0, option_parse_exclude },\n+\t\t\t0, apply_option_parse_exclude },\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\t0, apply_option_parse_include },\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\t\t0, apply_option_parse_p },\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@@ -4752,13 +4752,13 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\n \t\t\t\tN_(\"ensure at least <n> lines of context match\")),\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\t0, apply_option_parse_whitespace },\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\tPARSE_OPT_NOARG, apply_option_parse_space_change },\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\t\tPARSE_OPT_NOARG, apply_option_parse_space_change },\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@@ -4776,7 +4776,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\n \t\t\tRECOUNT),\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\t\t0, apply_option_parse_directory },\n \t\tOPT_END()\n \t};\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286215","messageId":"20160511131745.2914-79-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 78/94] apply: rename and move opt constants to apply.h","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:29Z","receivedAt":"2016-05-11T13:17:29Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"The constants for the \"inaccurate-eof\" and the \"recount\" options will\nbe used in both \"apply.c\" and \"builtin/apply.c\", so they need to go\ninto \"apply.h\", and therefore they need a name that is more specific\nto the API they belong to.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.h         |  3 +++\n builtin/apply.c | 11 ++++-------\n 2 files changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/apply.h b/apply.h\nindex 5266612..60e0c2f 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -122,4 +122,7 @@ extern int init_apply_state(struct apply_state *state,\n \t\t\t    struct lock_file *lock_file);\n extern int check_apply_state(struct apply_state *state, int force_apply);\n \n+#define APPLY_OPT_INACCURATE_EOF\t(1<<0)\n+#define APPLY_OPT_RECOUNT\t\t(1<<1)\n+\n #endif\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex f05dc96..9ce177b 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -4448,9 +4448,6 @@ static int write_out_results(struct apply_state *state, struct patch *list)\n \treturn errs;\n }\n \n-#define INACCURATE_EOF\t(1<<0)\n-#define RECOUNT\t\t(1<<1)\n-\n /*\n  * Try to apply a patch.\n  *\n@@ -4479,8 +4476,8 @@ static int apply_patch(struct apply_state *state,\n \t\tint nr;\n \n \t\tpatch = xcalloc(1, sizeof(*patch));\n-\t\tpatch->inaccurate_eof = !!(options & INACCURATE_EOF);\n-\t\tpatch->recount =  !!(options & RECOUNT);\n+\t\tpatch->inaccurate_eof = !!(options & APPLY_OPT_INACCURATE_EOF);\n+\t\tpatch->recount =  !!(options & APPLY_OPT_RECOUNT);\n \t\tnr = parse_chunk(state, buf.buf + offset, buf.len - offset, patch);\n \t\tif (nr < 0) {\n \t\t\tfree_patch(patch);\n@@ -4770,10 +4767,10 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\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+\t\t\tAPPLY_OPT_INACCURATE_EOF),\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\tAPPLY_OPT_RECOUNT),\n \t\t{ OPTION_CALLBACK, 0, \"directory\", &state, N_(\"root\"),\n \t\t\tN_(\"prepend <root> to all filenames\"),\n \t\t\t0, apply_option_parse_directory },\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286217","messageId":"20160511131745.2914-81-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 80/94] apply: make some parsing functions static again","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:31Z","receivedAt":"2016-05-11T13:17:31Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Some parsing functions that were used in both \"apply.c\" and\n\"builtin/apply.c\" are now only used in the former, so they\ncan be made static to \"apply.c\".\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.c | 6 +++---\n apply.h | 5 -----\n 2 files changed, 3 insertions(+), 8 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 537221b..3285bf7 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -27,7 +27,7 @@ static void git_apply_config(void)\n \tgit_config(git_default_config, NULL);\n }\n \n-int parse_whitespace_option(struct apply_state *state, const char *option)\n+static int parse_whitespace_option(struct apply_state *state, const char *option)\n {\n \tif (!option) {\n \t\tstate->ws_error_action = warn_on_ws_error;\n@@ -57,8 +57,8 @@ int parse_whitespace_option(struct apply_state *state, const char *option)\n \treturn error(_(\"unrecognized whitespace option '%s'\"), option);\n }\n \n-int parse_ignorewhitespace_option(struct apply_state *state,\n-\t\t\t\t  const char *option)\n+static int parse_ignorewhitespace_option(struct apply_state *state,\n+\t\t\t\t\t\t const char *option)\n {\n \tif (!option || !strcmp(option, \"no\") ||\n \t    !strcmp(option, \"false\") || !strcmp(option, \"never\") ||\ndiff --git a/apply.h b/apply.h\nindex c8b79ce..27b26a2 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -112,11 +112,6 @@ struct apply_state {\n \tenum ws_ignore ws_ignore_action;\n };\n \n-extern int parse_whitespace_option(struct apply_state *state,\n-\t\t\t\t   const char *option);\n-extern int parse_ignorewhitespace_option(struct apply_state *state,\n-\t\t\t\t\t const char *option);\n-\n extern int apply_option_parse_exclude(const struct option *opt,\n \t\t\t\t      const char *arg, int unset);\n extern int apply_option_parse_include(const struct option *opt,\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286232","messageId":"20160511131745.2914-82-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 81/94] run-command: make dup_devnull() non static","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:32Z","receivedAt":"2016-05-11T13:17:32Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"We will need this function in a later commit to redirect stdout\nand stderr to /dev/null.\n\nHelped-by: Johannes Sixt <j6t@kdbg.org>\nHelped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n run-command.c | 2 +-\n run-command.h | 6 ++++++\n 2 files changed, 7 insertions(+), 1 deletion(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex e4593cd..5d1cedf 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -85,7 +85,7 @@ static inline void close_pair(int fd[2])\n }\n \n #ifndef GIT_WINDOWS_NATIVE\n-static inline void dup_devnull(int to)\n+void dup_devnull(int to)\n {\n \tint fd = open(\"/dev/null\", O_RDWR);\n \tif (fd < 0)\ndiff --git a/run-command.h b/run-command.h\nindex 11f76b0..e05ce7d 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -201,4 +201,10 @@ int run_processes_parallel(int n,\n \t\t\t   task_finished_fn,\n \t\t\t   void *pp_cb);\n \n+/**\n+ * Misc helper functions\n+ */\n+\n+void dup_devnull(int to);\n+\n #endif\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286223","messageId":"20160511131745.2914-83-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 82/94] apply: roll back index lock file in case of error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:33Z","receivedAt":"2016-05-11T13:17:33Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"According to the lockfile API, when finished with a lockfile, one\nshould either commit it or roll it back.\n\nThis is even more important now that the same lockfile can be passed\nto init_apply_state() many times to be reused by series of calls to\nthe apply lib functions.\n\nHelped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.c | 31 +++++++++++++++++++++----------\n 1 file changed, 21 insertions(+), 10 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 3285bf7..7480ae8 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -4739,7 +4739,7 @@ int apply_all_patches(struct apply_state *state,\n \t\tif (!strcmp(arg, \"-\")) {\n \t\t\tres = apply_patch(state, 0, \"<stdin>\", options);\n \t\t\tif (res < 0)\n-\t\t\t\treturn -1;\n+\t\t\t\tgoto rollback_end;\n \t\t\terrs |= res;\n \t\t\tread_stdin = 0;\n \t\t\tcontinue;\n@@ -4749,21 +4749,23 @@ int apply_all_patches(struct apply_state *state,\n \t\t\t\t\t      arg);\n \n \t\tfd = open(arg, O_RDONLY);\n-\t\tif (fd < 0)\n-\t\t\treturn error(_(\"can't open patch '%s': %s\"), arg, strerror(errno));\n+\t\tif (fd < 0) {\n+\t\t\terror(_(\"can't open patch '%s': %s\"), arg, strerror(errno));\n+\t\t\tgoto rollback_end;\n+\t\t}\n \t\tread_stdin = 0;\n \t\tset_default_whitespace_mode(state);\n \t\tres = apply_patch(state, fd, arg, options);\n \t\tclose(fd);\n \t\tif (res < 0)\n-\t\t\treturn -1;\n+\t\t\tgoto rollback_end;\n \t\terrs |= res;\n \t}\n \tset_default_whitespace_mode(state);\n \tif (read_stdin) {\n \t\tres = apply_patch(state, 0, \"<stdin>\", options);\n \t\tif (res < 0)\n-\t\t\treturn -1;\n+\t\t\tgoto rollback_end;\n \t\terrs |= res;\n \t}\n \n@@ -4777,11 +4779,13 @@ int apply_all_patches(struct apply_state *state,\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\treturn error(Q_(\"%d line adds whitespace errors.\",\n-\t\t\t\t\t\"%d lines add whitespace errors.\",\n-\t\t\t\t\tstate->whitespace_error),\n-\t\t\t\t     state->whitespace_error);\n+\t\tif (state->ws_error_action == die_on_ws_error) {\n+\t\t\terror(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      state->whitespace_error);\n+\t\t\tgoto rollback_end;\n+\t\t}\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@@ -4802,5 +4806,12 @@ int apply_all_patches(struct apply_state *state,\n \t}\n \n \treturn !!errs;\n+\n+rollback_end:\n+\tif (state->newfd >= 0) {\n+\t\trollback_lock_file(state->lock_file);\n+\t\tstate->newfd = -1;\n+\t}\n+\treturn -1;\n }\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286220","messageId":"20160511131745.2914-84-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 83/94] environment: add set_index_file()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:34Z","receivedAt":"2016-05-11T13:17:34Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Introduce set_index_file() to be able to temporarily change the index file.\n\nIt should be used like this:\n\n    /* Save current index file */\n    old_index_file = get_index_file();\n    set_index_file((char *)tmp_index_file);\n\n    /* Do stuff that will use tmp_index_file as the index file */\n    ...\n\n    /* When finished reset the index file */\n    set_index_file(old_index_file);\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n cache.h       |  1 +\n environment.c | 10 ++++++++++\n 2 files changed, 11 insertions(+)\n\ndiff --git a/cache.h b/cache.h\nindex 160f8e3..452d0ec 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -461,6 +461,7 @@ extern int is_inside_work_tree(void);\n extern const char *get_git_dir(void);\n extern const char *get_git_common_dir(void);\n extern char *get_object_directory(void);\n+extern void set_index_file(char *index_file);\n extern char *get_index_file(void);\n extern char *get_graft_file(void);\n extern int set_git_dir(const char *path);\ndiff --git a/environment.c b/environment.c\nindex 57acb2f..9676d2a 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -290,6 +290,16 @@ int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1)\n \treturn open(name, O_RDWR|O_CREAT|O_EXCL, 0600);\n }\n \n+/*\n+ * Temporarily change the index file.\n+ * Please save the current index file using get_index_file() before changing\n+ * the index file. And when finished, reset it to the saved value.\n+ */\n+void set_index_file(char *index_file)\n+{\n+\tgit_index_file = index_file;\n+}\n+\n char *get_index_file(void)\n {\n \tif (!git_index_file)\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286219","messageId":"20160511131745.2914-85-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 84/94] builtin/am: use apply api in run_apply()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:35Z","receivedAt":"2016-05-11T13:17:35Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This replaces run_apply() implementation with a new one that\nuses the apply api that has been previously prepared in\napply.c and apply.h.\n\nThis shoud improve performance a lot in certain cases.\n\nAs the previous implementation was creating a new `git apply`\nprocess to apply each patch, it could be slow on systems like\nWindows where it is costly to create new processes.\n\nAlso the new `git apply` process had to read the index from\ndisk, and when the process was done the calling process\ndiscarded its own index and read back from disk the new\nindex that had been created by the `git apply` process.\n\nThis could be very inefficient with big repositories that\nhave big index files, especially when the system decided\nthat it was a good idea to run the `git apply` processes on\na different processor core.\n\nAlso eliminating index reads enables further performance\nimprovements by using:\n\n`git update-index --split-index`\n\nFor example here is a benchmark of a multi hundred commit\nrebase on the Linux kernel on a Debian laptop with SSD:\n\ncommand: git rebase --onto 1993b17 52bef0c 29dde7c\n\nVanilla \"next\" without split index:                1m54.953s\nVanilla \"next\" with split index:                   1m22.476s\nThis series on top of \"next\" without split index:  1m12.034s\nThis series on top of \"next\" with split index:     0m15.678s\n\n(using branch \"next\" from mid April 2016.)\n\nBenchmarked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/am.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++-----------\n 1 file changed, 86 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex d003939..cc66a48 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -28,6 +28,7 @@\n #include \"rerere.h\"\n #include \"prompt.h\"\n #include \"mailinfo.h\"\n+#include \"apply.h\"\n \n /**\n  * Returns 1 if the file is empty or does not exist, 0 otherwise.\n@@ -1522,39 +1523,106 @@ static int parse_mail_rebase(struct am_state *state, const char *mail)\n  */\n static int run_apply(const struct am_state *state, const char *index_file)\n {\n-\tstruct child_process cp = CHILD_PROCESS_INIT;\n-\n-\tcp.git_cmd = 1;\n-\n-\tif (index_file)\n-\t\targv_array_pushf(&cp.env_array, \"GIT_INDEX_FILE=%s\", index_file);\n+\tstruct argv_array apply_paths = ARGV_ARRAY_INIT;\n+\tstruct argv_array apply_opts = ARGV_ARRAY_INIT;\n+\tstruct apply_state apply_state;\n+\tint save_stdout_fd, save_stderr_fd;\n+\tint res, opts_left;\n+\tchar *save_index_file;\n+\tstatic struct lock_file lock_file;\n+\n+\tstruct option am_apply_options[] = {\n+\t\t{ OPTION_CALLBACK, 0, \"whitespace\", &apply_state, N_(\"action\"),\n+\t\t\tN_(\"detect new or modified lines that have whitespace errors\"),\n+\t\t\t0, apply_option_parse_whitespace },\n+\t\t{ OPTION_CALLBACK, 0, \"ignore-space-change\", &apply_state, NULL,\n+\t\t\tN_(\"ignore changes in whitespace when finding context\"),\n+\t\t\tPARSE_OPT_NOARG, apply_option_parse_space_change },\n+\t\t{ OPTION_CALLBACK, 0, \"ignore-whitespace\", &apply_state, NULL,\n+\t\t\tN_(\"ignore changes in whitespace when finding context\"),\n+\t\t\tPARSE_OPT_NOARG, apply_option_parse_space_change },\n+\t\t{ OPTION_CALLBACK, 0, \"directory\", &apply_state, N_(\"root\"),\n+\t\t\tN_(\"prepend <root> to all filenames\"),\n+\t\t\t0, apply_option_parse_directory },\n+\t\t{ OPTION_CALLBACK, 0, \"exclude\", &apply_state, N_(\"path\"),\n+\t\t\tN_(\"don't apply changes matching the given path\"),\n+\t\t\t0, apply_option_parse_exclude },\n+\t\t{ OPTION_CALLBACK, 0, \"include\", &apply_state, N_(\"path\"),\n+\t\t\tN_(\"apply changes matching the given path\"),\n+\t\t\t0, apply_option_parse_include },\n+\t\tOPT_INTEGER('C', NULL, &apply_state.p_context,\n+\t\t\t\tN_(\"ensure at least <n> lines of context match\")),\n+\t\t{ OPTION_CALLBACK, 'p', NULL, &apply_state, N_(\"num\"),\n+\t\t\tN_(\"remove <num> leading slashes from traditional diff paths\"),\n+\t\t\t0, apply_option_parse_p },\n+\t\tOPT_BOOL(0, \"reject\", &apply_state.apply_with_reject,\n+\t\t\tN_(\"leave the rejected hunks in corresponding *.rej files\")),\n+\t\tOPT_END()\n+\t};\n \n \t/*\n \t * If we are allowed to fall back on 3-way merge, don't give false\n \t * errors during the initial attempt.\n \t */\n+\n \tif (state->threeway && !index_file) {\n-\t\tcp.no_stdout = 1;\n-\t\tcp.no_stderr = 1;\n+\t\tsave_stdout_fd = dup(1);\n+\t\tdup_devnull(1);\n+\t\tsave_stderr_fd = dup(2);\n+\t\tdup_devnull(2);\n \t}\n \n-\targv_array_push(&cp.args, \"apply\");\n+\tif (index_file) {\n+\t\tsave_index_file = get_index_file();\n+\t\tset_index_file((char *)index_file);\n+\t}\n \n-\targv_array_pushv(&cp.args, state->git_apply_opts.argv);\n+\tif (init_apply_state(&apply_state, NULL, &lock_file))\n+\t\tdie(\"init_apply_state() failed\");\n+\n+\targv_array_push(&apply_opts, \"apply\");\n+\targv_array_pushv(&apply_opts, state->git_apply_opts.argv);\n+\n+\topts_left = parse_options(apply_opts.argc, apply_opts.argv,\n+\t\t\t\t  NULL, am_apply_options, NULL, 0);\n+\n+\tif (opts_left != 0)\n+\t\tdie(\"unknown option passed thru to git apply\");\n \n \tif (index_file)\n-\t\targv_array_push(&cp.args, \"--cached\");\n+\t\tapply_state.cached = 1;\n \telse\n-\t\targv_array_push(&cp.args, \"--index\");\n+\t\tapply_state.check_index = 1;\n \n-\targv_array_push(&cp.args, am_path(state, \"patch\"));\n+\tif (check_apply_state(&apply_state, 0))\n+\t\tdie(\"check_apply_state() failed\");\n \n-\tif (run_command(&cp))\n-\t\treturn -1;\n+\targv_array_push(&apply_paths, am_path(state, \"patch\"));\n \n-\t/* Reload index as git-apply will have modified it. */\n-\tdiscard_cache();\n-\tread_cache_from(index_file ? index_file : get_index_file());\n+\tres = apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, 0);\n+\n+\t/* Restore stdout and stderr */\n+\tif (state->threeway && !index_file) {\n+\t\tdup2(save_stdout_fd, 1);\n+\t\tclose(save_stdout_fd);\n+\t\tdup2(save_stderr_fd, 2);\n+\t\tclose(save_stderr_fd);\n+\t}\n+\n+\tif (index_file)\n+\t\tset_index_file(save_index_file);\n+\n+\targv_array_clear(&apply_paths);\n+\targv_array_clear(&apply_opts);\n+\n+\tif (res)\n+\t\treturn res;\n+\n+\tif (index_file) {\n+\t\t/* Reload index as apply_all_patches() will have modified it. */\n+\t\tdiscard_cache();\n+\t\tread_cache_from(index_file);\n+\t}\n \n \treturn 0;\n }\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286230","messageId":"20160511131745.2914-86-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 85/94] write_or_die: use warning() instead of fprintf(stderr, ...)","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:36Z","receivedAt":"2016-05-11T13:17: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 write_or_die.c | 6 ++----\n 1 file changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/write_or_die.c b/write_or_die.c\nindex 49e80aa..c29f677 100644\n--- a/write_or_die.c\n+++ b/write_or_die.c\n@@ -87,8 +87,7 @@ int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)\n {\n \tif (write_in_full(fd, buf, count) < 0) {\n \t\tcheck_pipe(errno);\n-\t\tfprintf(stderr, \"%s: write error (%s)\\n\",\n-\t\t\tmsg, strerror(errno));\n+\t\twarning(\"%s: write error (%s)\\n\", msg, strerror(errno));\n \t\treturn 0;\n \t}\n \n@@ -98,8 +97,7 @@ int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)\n int write_or_whine(int fd, const void *buf, size_t count, const char *msg)\n {\n \tif (write_in_full(fd, buf, count) < 0) {\n-\t\tfprintf(stderr, \"%s: write error (%s)\\n\",\n-\t\t\tmsg, strerror(errno));\n+\t\twarning(\"%s: write error (%s)\\n\", msg, strerror(errno));\n \t\treturn 0;\n \t}\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286222","messageId":"20160511131745.2914-87-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 86/94] apply: add 'be_silent' variable to 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:37Z","receivedAt":"2016-05-11T13:17:37Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This variable should prevent anything to be printed on both stderr\nand stdout.\n\nLet's not take care of stdout and apply_verbosely for now though,\nas that will be taken care of in following patches.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.c | 43 +++++++++++++++++++++++++++++--------------\n apply.h |  1 +\n 2 files changed, 30 insertions(+), 14 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 7480ae8..f69a61a 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -1600,8 +1600,9 @@ static void record_ws_error(struct apply_state *state,\n \t\treturn;\n \n \terr = whitespace_error_string(result);\n-\tfprintf(stderr, \"%s:%d: %s.\\n%.*s\\n\",\n-\t\tstate->patch_input_file, linenr, err, len, line);\n+\tif (!state->be_silent)\n+\t\tfprintf(stderr, \"%s:%d: %s.\\n%.*s\\n\",\n+\t\t\tstate->patch_input_file, linenr, err, len, line);\n \tfree(err);\n }\n \n@@ -1796,7 +1797,7 @@ static int parse_single_patch(struct apply_state *state,\n \t\treturn error(_(\"new file %s depends on old contents\"), patch->new_name);\n \tif (0 < patch->is_delete && newlines)\n \t\treturn error(_(\"deleted file %s still has contents\"), patch->old_name);\n-\tif (!patch->is_delete && !newlines && context)\n+\tif (!patch->is_delete && !newlines && context && !state->be_silent)\n \t\tfprintf_ln(stderr,\n \t\t\t   _(\"** warning: \"\n \t\t\t     \"file %s becomes empty but is not deleted\"),\n@@ -3020,8 +3021,8 @@ static int apply_one_fragment(struct apply_state *state,\n \t\t * Warn if it was necessary to reduce the number\n \t\t * of context lines.\n \t\t */\n-\t\tif ((leading != frag->leading) ||\n-\t\t    (trailing != frag->trailing))\n+\t\tif ((leading != frag->leading ||\n+\t\t     trailing != frag->trailing) && !state->be_silent)\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@@ -3518,7 +3519,8 @@ static int try_threeway(struct apply_state *state,\n \t\t read_blob_object(&buf, pre_sha1, patch->old_mode))\n \t\treturn error(\"repository lacks the necessary blob to fall back on 3-way merge.\");\n \n-\tfprintf(stderr, \"Falling back to three-way merge...\\n\");\n+\tif (!state->be_silent)\n+\t\tfprintf(stderr, \"Falling back to three-way merge...\\n\");\n \n \timg = strbuf_detach(&buf, &len);\n \tprepare_image(&tmp_image, img, len, 1);\n@@ -3548,7 +3550,9 @@ static int try_threeway(struct apply_state *state,\n \tstatus = three_way_merge(image, patch->new_name,\n \t\t\t\t pre_sha1, our_sha1, post_sha1);\n \tif (status < 0) {\n-\t\tfprintf(stderr, \"Failed to fall back on three-way merge...\\n\");\n+\t\tif (!state->be_silent)\n+\t\t\tfprintf(stderr,\n+\t\t\t\t\"Failed to fall back on three-way merge...\\n\");\n \t\treturn status;\n \t}\n \n@@ -3560,9 +3564,15 @@ static int try_threeway(struct apply_state *state,\n \t\t\thashcpy(patch->threeway_stage[0].hash, pre_sha1);\n \t\thashcpy(patch->threeway_stage[1].hash, our_sha1);\n \t\thashcpy(patch->threeway_stage[2].hash, post_sha1);\n-\t\tfprintf(stderr, \"Applied patch to '%s' with conflicts.\\n\", patch->new_name);\n+\t\tif (!state->be_silent)\n+\t\t\tfprintf(stderr,\n+\t\t\t\t\"Applied patch to '%s' with conflicts.\\n\",\n+\t\t\t\tpatch->new_name);\n \t} else {\n-\t\tfprintf(stderr, \"Applied patch to '%s' cleanly.\\n\", patch->new_name);\n+\t\tif (!state->be_silent)\n+\t\t\tfprintf(stderr,\n+\t\t\t\t\"Applied patch to '%s' cleanly.\\n\",\n+\t\t\t\tpatch->new_name);\n \t}\n \treturn 0;\n }\n@@ -4461,7 +4471,8 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)\n \t\t\t    \"Applying patch %%s with %d rejects...\",\n \t\t\t    cnt),\n \t\t    cnt);\n-\tsay_patch_name(stderr, sb.buf, patch);\n+\tif (!state->be_silent)\n+\t\tsay_patch_name(stderr, sb.buf, patch);\n \tstrbuf_release(&sb);\n \n \tcnt = strlen(patch->new_name);\n@@ -4488,10 +4499,12 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)\n \t     frag;\n \t     cnt++, frag = frag->next) {\n \t\tif (!frag->rejected) {\n-\t\t\tfprintf_ln(stderr, _(\"Hunk #%d applied cleanly.\"), cnt);\n+\t\t\tif (!state->be_silent)\n+\t\t\t\tfprintf_ln(stderr, _(\"Hunk #%d applied cleanly.\"), cnt);\n \t\t\tcontinue;\n \t\t}\n-\t\tfprintf_ln(stderr, _(\"Rejected hunk #%d.\"), cnt);\n+\t\tif (!state->be_silent)\n+\t\t\tfprintf_ln(stderr, _(\"Rejected hunk #%d.\"), cnt);\n \t\tfprintf(rej, \"%.*s\", frag->size, frag->patch);\n \t\tif (frag->patch[frag->size-1] != '\\n')\n \t\t\tfputc('\\n', rej);\n@@ -4540,8 +4553,10 @@ static int write_out_results(struct apply_state *state, struct patch *list)\n \t\tstruct string_list_item *item;\n \n \t\tstring_list_sort(&cpath);\n-\t\tfor_each_string_list_item(item, &cpath)\n-\t\t\tfprintf(stderr, \"U %s\\n\", item->string);\n+\t\tif (!state->be_silent) {\n+\t\t\tfor_each_string_list_item(item, &cpath)\n+\t\t\t\tfprintf(stderr, \"U %s\\n\", item->string);\n+\t\t}\n \t\tstring_list_clear(&cpath, 0);\n \n \t\trerere(0);\ndiff --git a/apply.h b/apply.h\nindex 27b26a2..2dd3706 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -44,6 +44,7 @@ struct apply_state {\n \tint apply_in_reverse;\n \tint apply_with_reject;\n \tint apply_verbosely;\n+\tint be_silent;\n \n \t/* --cached updates only the cache without ever touching the working tree. */\n \tint cached;\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286231","messageId":"20160511131745.2914-88-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 87/94] apply: make 'be_silent' incomatible with 'apply_verbosely'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:38Z","receivedAt":"2016-05-11T13:17:38Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"It should be an error to have both be_silent and apply_verbosely set,\nso let's check that in check_apply_state().\n\nAnd by the way let's not automatically set apply_verbosely when\nbe_silent is set.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n apply.c | 10 ++++++++--\n 1 file changed, 8 insertions(+), 2 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex f69a61a..5459ee1 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -113,8 +113,11 @@ int check_apply_state(struct apply_state *state, int force_apply)\n \t\t\treturn error(_(\"--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 (state->apply_with_reject) {\n+\t\tstate->apply = 1;\n+\t\tif (!state->be_silent)\n+\t\t\tstate->apply_verbosely = 1;\n+\t}\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@@ -126,6 +129,9 @@ int check_apply_state(struct apply_state *state, int force_apply)\n \t}\n \tif (state->check_index)\n \t\tstate->unsafe_paths = 0;\n+\tif (state->be_silent && state->apply_verbosely)\n+\t\treturn error(_(\"incompatible internal 'be_silent' and 'apply_verbosely' flags\"));\n+\n \treturn 0;\n }\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286226","messageId":"20160511131745.2914-89-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 88/94] apply: don't print on stdout when be_silent is set","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:39Z","receivedAt":"2016-05-11T13:17: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 apply.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 5459ee1..e0fdd1d 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -4669,13 +4669,13 @@ static int apply_patch(struct apply_state *state,\n \t\tgoto end;\n \t}\n \n-\tif (state->diffstat)\n+\tif (state->diffstat && !state->be_silent)\n \t\tstat_patch_list(state, list);\n \n-\tif (state->numstat)\n+\tif (state->numstat && !state->be_silent)\n \t\tnumstat_patch_list(state, list);\n \n-\tif (state->summary)\n+\tif (state->summary && !state->be_silent)\n \t\tsummary_patch_list(list);\n \n end:\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286228","messageId":"20160511131745.2914-90-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 89/94] usage: add set_warn_routine()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:40Z","receivedAt":"2016-05-11T13:17:40Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"There are already set_die_routine() and set_error_routine(),\nso let's add set_warn_routine() as this will be needed in a\nfollowing commit.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n git-compat-util.h | 1 +\n usage.c           | 5 +++++\n 2 files changed, 6 insertions(+)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 1f8b5f3..987eb99 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -438,6 +438,7 @@ static inline int const_error(void)\n \n extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));\n extern void set_error_routine(void (*routine)(const char *err, va_list params));\n+extern void set_warn_routine(void (*routine)(const char *warn, va_list params));\n extern void set_die_is_recursing_routine(int (*routine)(void));\n extern void set_error_handle(FILE *);\n \ndiff --git a/usage.c b/usage.c\nindex 82ff131..8fbedb3 100644\n--- a/usage.c\n+++ b/usage.c\n@@ -70,6 +70,11 @@ void set_error_routine(void (*routine)(const char *err, va_list params))\n \terror_routine = routine;\n }\n \n+void set_warn_routine(void (*routine)(const char *warn, va_list params))\n+{\n+\twarn_routine = routine;\n+}\n+\n void set_die_is_recursing_routine(int (*routine)(void))\n {\n \tdie_is_recursing = routine;\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286221","messageId":"20160511131745.2914-91-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 90/94] usage: add get_error_routine() and get_warn_routine()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:41Z","receivedAt":"2016-05-11T13:17:41Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Let's make it possible to get the current error_routine and warn_routine,\nso that we can store them before using set_error_routine() or\nset_warn_routine() to use new ones.\n\nThis way we will be able put back the original routines, when we are done\nwith using new ones.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n git-compat-util.h |  2 ++\n usage.c           | 10 ++++++++++\n 2 files changed, 12 insertions(+)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 987eb99..73446af 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -438,7 +438,9 @@ static inline int const_error(void)\n \n extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));\n extern void set_error_routine(void (*routine)(const char *err, va_list params));\n+extern void (*get_error_routine(void))(const char *err, va_list params);\n extern void set_warn_routine(void (*routine)(const char *warn, va_list params));\n+extern void (*get_warn_routine(void))(const char *warn, va_list params);\n extern void set_die_is_recursing_routine(int (*routine)(void));\n extern void set_error_handle(FILE *);\n \ndiff --git a/usage.c b/usage.c\nindex 8fbedb3..825bd92 100644\n--- a/usage.c\n+++ b/usage.c\n@@ -70,11 +70,21 @@ void set_error_routine(void (*routine)(const char *err, va_list params))\n \terror_routine = routine;\n }\n \n+void (*get_error_routine(void))(const char *err, va_list params)\n+{\n+\treturn error_routine;\n+}\n+\n void set_warn_routine(void (*routine)(const char *warn, va_list params))\n {\n \twarn_routine = routine;\n }\n \n+void (*get_warn_routine(void))(const char *warn, va_list params)\n+{\n+\treturn warn_routine;\n+}\n+\n void set_die_is_recursing_routine(int (*routine)(void))\n {\n \tdie_is_recursing = routine;\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286225","messageId":"20160511131745.2914-92-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 91/94] apply: change error_routine when be_silent is set","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:42Z","receivedAt":"2016-05-11T13:17: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 apply.c | 29 +++++++++++++++++++++++++----\n apply.h |  3 +++\n 2 files changed, 28 insertions(+), 4 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex e0fdd1d..1dafc82 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -100,6 +100,11 @@ int init_apply_state(struct apply_state *state,\n \treturn 0;\n }\n \n+static void mute_routine(const char *bla, va_list params)\n+{\n+\t/* do nothing */\n+}\n+\n int check_apply_state(struct apply_state *state, int force_apply)\n {\n \tint is_not_gitdir = !startup_info->have_repository;\n@@ -132,6 +137,13 @@ int check_apply_state(struct apply_state *state, int force_apply)\n \tif (state->be_silent && state->apply_verbosely)\n \t\treturn error(_(\"incompatible internal 'be_silent' and 'apply_verbosely' flags\"));\n \n+\tif (state->be_silent) {\n+\t\tstate->saved_error_routine = get_error_routine();\n+\t\tstate->saved_warn_routine = get_warn_routine();\n+\t\tset_error_routine(mute_routine);\n+\t\tset_warn_routine(mute_routine);\n+\t}\n+\n \treturn 0;\n }\n \n@@ -4750,6 +4762,7 @@ int apply_all_patches(struct apply_state *state,\n {\n \tint i;\n \tint res;\n+\tint retval = -1;\n \tint errs = 0;\n \tint read_stdin = 1;\n \n@@ -4822,17 +4835,25 @@ int apply_all_patches(struct apply_state *state,\n \tif (state->update_index) {\n \t\tres = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);\n \t\tstate->newfd = -1;\n-\t\tif (res)\n-\t\t\treturn error(_(\"Unable to write new index file\"));\n+\t\tif (res) {\n+\t\t\terror(_(\"Unable to write new index file\"));\n+\t\t\tgoto rollback_end;\n+\t\t}\n \t}\n \n-\treturn !!errs;\n+\tretval = !!errs;\n \n rollback_end:\n \tif (state->newfd >= 0) {\n \t\trollback_lock_file(state->lock_file);\n \t\tstate->newfd = -1;\n \t}\n-\treturn -1;\n+\n+\tif (state->be_silent) {\n+\t\tset_error_routine(state->saved_error_routine);\n+\t\tset_warn_routine(state->saved_warn_routine);\n+\t}\n+\n+\treturn retval;\n }\n \ndiff --git a/apply.h b/apply.h\nindex 2dd3706..029b79f 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -46,6 +46,9 @@ struct apply_state {\n \tint apply_verbosely;\n \tint be_silent;\n \n+\tvoid (*saved_error_routine)(const char *err, va_list params);\n+\tvoid (*saved_warn_routine)(const char *warn, va_list params);\n+\n \t/* --cached updates only the cache without ever touching the working tree. */\n \tint cached;\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286227","messageId":"20160511131745.2914-93-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 92/94] am: use be_silent in 'struct apply_state' to shut up applying patches","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:43Z","receivedAt":"2016-05-11T13:17: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/am.c | 29 ++++++++---------------------\n 1 file changed, 8 insertions(+), 21 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex cc66a48..c158c4d 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1526,7 +1526,6 @@ static int run_apply(const struct am_state *state, const char *index_file)\n \tstruct argv_array apply_paths = ARGV_ARRAY_INIT;\n \tstruct argv_array apply_opts = ARGV_ARRAY_INIT;\n \tstruct apply_state apply_state;\n-\tint save_stdout_fd, save_stderr_fd;\n \tint res, opts_left;\n \tchar *save_index_file;\n \tstatic struct lock_file lock_file;\n@@ -1560,18 +1559,6 @@ static int run_apply(const struct am_state *state, const char *index_file)\n \t\tOPT_END()\n \t};\n \n-\t/*\n-\t * If we are allowed to fall back on 3-way merge, don't give false\n-\t * errors during the initial attempt.\n-\t */\n-\n-\tif (state->threeway && !index_file) {\n-\t\tsave_stdout_fd = dup(1);\n-\t\tdup_devnull(1);\n-\t\tsave_stderr_fd = dup(2);\n-\t\tdup_devnull(2);\n-\t}\n-\n \tif (index_file) {\n \t\tsave_index_file = get_index_file();\n \t\tset_index_file((char *)index_file);\n@@ -1594,6 +1581,14 @@ static int run_apply(const struct am_state *state, const char *index_file)\n \telse\n \t\tapply_state.check_index = 1;\n \n+\t/*\n+\t * If we are allowed to fall back on 3-way merge, don't give false\n+\t * errors during the initial attempt.\n+\t */\n+\n+\tif (state->threeway && !index_file)\n+\t\tapply_state.be_silent = 1;\n+\n \tif (check_apply_state(&apply_state, 0))\n \t\tdie(\"check_apply_state() failed\");\n \n@@ -1601,14 +1596,6 @@ static int run_apply(const struct am_state *state, const char *index_file)\n \n \tres = apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, 0);\n \n-\t/* Restore stdout and stderr */\n-\tif (state->threeway && !index_file) {\n-\t\tdup2(save_stdout_fd, 1);\n-\t\tclose(save_stdout_fd);\n-\t\tdup2(save_stderr_fd, 2);\n-\t\tclose(save_stderr_fd);\n-\t}\n-\n \tif (index_file)\n \t\tset_index_file(save_index_file);\n \n-- \n2.8.2.490.g3dabe57\n"},{"id":"286224","messageId":"20160511131745.2914-94-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 93/94] run-command: make dup_devnull() static again","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:44Z","receivedAt":"2016-05-11T13:17:44Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"As there is no caller of dup_devnull() outside run-command.c any more,\nlet's make dup_devnull() static again.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n run-command.c | 2 +-\n run-command.h | 6 ------\n 2 files changed, 1 insertion(+), 7 deletions(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex 5d1cedf..e524e34 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -85,7 +85,7 @@ static inline void close_pair(int fd[2])\n }\n \n #ifndef GIT_WINDOWS_NATIVE\n-void dup_devnull(int to)\n+static void dup_devnull(int to)\n {\n \tint fd = open(\"/dev/null\", O_RDWR);\n \tif (fd < 0)\ndiff --git a/run-command.h b/run-command.h\nindex e05ce7d..11f76b0 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -201,10 +201,4 @@ int run_processes_parallel(int n,\n \t\t\t   task_finished_fn,\n \t\t\t   void *pp_cb);\n \n-/**\n- * Misc helper functions\n- */\n-\n-void dup_devnull(int to);\n-\n #endif\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286229","messageId":"20160511131745.2914-95-chriscool@tuxfamily.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"[PATCH v2 94/94] builtin/apply: add a cli option for be_silent","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-11T13:17:45Z","receivedAt":"2016-05-11T13:17:45Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Let's make it possible to request a silent operation on the\ncommand line.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/apply.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex ce12769..397ef26 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -70,6 +70,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\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_BOOL(0, \"silent\", &state.be_silent,\n+\t\t\tN_(\"do not print any output\")),\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\tAPPLY_OPT_INACCURATE_EOF),\n-- \n2.8.2.490.g3dabe57\n"},{"id":"286342","messageId":"5734B805.8020504@kdbg.org","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2016-05-12T17:06:13Z","receivedAt":"2016-05-12T17:06:13Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 11.05.2016 um 15:16 schrieb Christian Couder:\n> This is a patch series about libifying `git apply` functionality, and\n> using this libified functionality in `git am`, so that no 'git apply'\n> process is spawn anymore. This makes `git am` significantly faster, so\n> `git rebase`, when it uses the am backend, is also significantly\n> faster.\n\nI'm including this in my build on Windows. It passes the test suite.\n\nI'll also use it in production for a while, although I am not a git-am \nconsumer nor do I use git-rebase without -i, hence, my tests will \nprobably only show that there is no bad fall-out.\n\n-- Hannes\n"},{"id":"286345","messageId":"CAP8UFD1ukOMi_VDKzZErwSu1OBU5h1hVOxd7mPu1ytzFr11VGA@mail.gmail.com","threadId":"42281","inReplyTo":"5734B805.8020504@kdbg.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-12T18:02:02Z","receivedAt":"2016-05-12T18:02:02Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, May 12, 2016 at 7:06 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 11.05.2016 um 15:16 schrieb Christian Couder:\n>>\n>> This is a patch series about libifying `git apply` functionality, and\n>> using this libified functionality in `git am`, so that no 'git apply'\n>> process is spawn anymore. This makes `git am` significantly faster, so\n>> `git rebase`, when it uses the am backend, is also significantly\n>> faster.\n>\n>\n> I'm including this in my build on Windows. It passes the test suite.\n\nGreat! Thanks for the report!\n\n> I'll also use it in production for a while, although I am not a git-am\n> consumer nor do I use git-rebase without -i, hence, my tests will probably\n> only show that there is no bad fall-out.\n\nThanks anyway,\nChristian.\n"},{"id":"286349","messageId":"xmqqr3d7f68l.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"5734B805.8020504@kdbg.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:04:10Z","receivedAt":"2016-05-12T19:04:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j6t@kdbg.org> writes:\n\n> I'll also use it in production for a while, although I am not a git-am\n> consumer nor do I use git-rebase without -i, hence, my tests will\n> probably only show that there is no bad fall-out.\n\nIt will probably only show that you do not use the part that was\ntouched by the series ;-)\n\nAs Christian said in 00/94, this probably needs to go in steps, as I\ndo not think anybody wants to review fouteen rounds of 90+ patch\nseries.  I thought the early 40+ patches in the series were at least\ncursory reviewed already?\n"},{"id":"286350","messageId":"xmqqmvnvf65c.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-2-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 01/94] builtin/apply: make gitdiff_verify_name() return void","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:06:07Z","receivedAt":"2016-05-12T19:06:07Z","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> As the value returned by gitdiff_verify_name() is put into the\n> same variable that is passed as a parameter to this function,\n> it is simpler to pass the address of the variable and have\n> gitdiff_verify_name() change the variable itself.\n>\n> This also makes it possible to later have this function return\n> -1 instead of die()ing in case of error.\n>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n\nWhile I do not agree with \"it is simpler\" at all (it makes it harder\nfor callers if they ever want to use different variables--they would\nneed to invent a temporary variable just for that, and it makes it\nno difference for existing callers that happen to use the same\nvariable), I like the way the real reason why we want to do this is\nmentioned in the proposed log message.\n\nWill queue.\n\n>  builtin/apply.c | 26 +++++++++++++-------------\n>  1 file changed, 13 insertions(+), 13 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index 8e4da2e..fe5aebd 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -925,43 +925,43 @@ 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 void gitdiff_verify_name(const char *line, int isnull, char **name, int side)\n>  {\n> -\tif (!orig_name && !isnull)\n> -\t\treturn find_name(line, NULL, p_value, TERM_TAB);\n> +\tif (!*name && !isnull) {\n> +\t\t*name = find_name(line, NULL, p_value, TERM_TAB);\n> +\t\treturn;\n> +\t}\n>  \n> -\tif (orig_name) {\n> -\t\tint len = strlen(orig_name);\n> +\tif (*name) {\n> +\t\tint len = strlen(*name);\n>  \t\tchar *another;\n>  \t\tif (isnull)\n>  \t\t\tdie(_(\"git apply: bad git-diff - expected /dev/null, got %s on line %d\"),\n> -\t\t\t    orig_name, linenr);\n> +\t\t\t    *name, linenr);\n>  \t\tanother = find_name(line, NULL, p_value, TERM_TAB);\n> -\t\tif (!another || memcmp(another, orig_name, len + 1))\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\tfree(another);\n> -\t\treturn orig_name;\n>  \t} else {\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\treturn NULL;\n>  \t}\n>  }\n>  \n>  static int gitdiff_oldname(const char *line, struct patch *patch)\n>  {\n> -\tpatch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name,\n> -\t\t\t\t\t      DIFF_OLD_NAME);\n> +\tgitdiff_verify_name(line, patch->is_new, &patch->old_name,\n> +\t\t\t    DIFF_OLD_NAME);\n>  \treturn 0;\n>  }\n>  \n>  static int gitdiff_newname(const char *line, struct patch *patch)\n>  {\n> -\tpatch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name,\n> -\t\t\t\t\t      DIFF_NEW_NAME);\n> +\tgitdiff_verify_name(line, patch->is_delete, &patch->new_name,\n> +\t\t\t    DIFF_NEW_NAME);\n>  \treturn 0;\n>  }\n"},{"id":"286351","messageId":"xmqqinyjf5zj.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-3-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 02/94] builtin/apply: avoid parameter shadowing 'p_value' global","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:09:36Z","receivedAt":"2016-05-12T19:09:36Z","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> Let's just rename the global 'state_p_value' as it will become\n> 'state->p_value' in a following patch.\n>\n> This also avoid errors when compiling with -Wshadow and makes\n> it safer to later move global variables into a \"state\" struct.\n\nLooks correctly done (I looked at remaining instances of \"p_value\").\n\nWill queue.  Thanks.\n"},{"id":"286352","messageId":"xmqqeg97f5x4.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-4-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 03/94] builtin/apply: avoid parameter shadowing 'linenr' global","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:11:03Z","receivedAt":"2016-05-12T19:11:03Z","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> Let's just rename the global 'state_linenr' as it will become\n> 'state->linenr' in a following patch.\n>\n> This also avoid errors when compiling with -Wshadow and makes\n> it safer to later move global variables into a \"state\" struct.\n\nLooks correctly done (I looked at remaining instances of \"linenr\").\n\nWill queue.  Thanks.\n"},{"id":"286353","messageId":"xmqqa8jvf5gn.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-6-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 05/94] builtin/apply: extract line_by_line_fuzzy_match() from match_fragment()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:20:56Z","receivedAt":"2016-05-12T19:20:56Z","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> The match_fragment() function is very big and contains a big special case\n> algorithm that does line by line fuzzy matching. So let's extract this\n> algorithm in a separate line_by_line_fuzzy_match() function.\n>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n\nLooks good.\n\nI am puzzled by the \"git blame -w -M\" output after applying this\npatch, though.  The body of the new function came more or less\nverbatim from the origina with reindentation.\n"},{"id":"286354","messageId":"xmqq60ujf593.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-10-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 09/94] builtin/apply: move 'state' init into init_apply_state()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:25:28Z","receivedAt":"2016-05-12T19:25:28Z","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> When the apply functionality will be libified, the 'struct apply_state'\n> will be used by different pieces of code.\n>\n> To properly initialize a 'struct apply_state', let's provide a nice\n> and easy to use init_apply_state() function.\n\nThis probably should be done at 08/94, but I'll let it pass for now.\nI am hoping 'prefix' is just one of a very few parameters this\nfunction needs to take to initialize this (I do not think we want to\nfeed many different parameters to this function to initialize).\n\nWill queue.\n\n> Helped-by: Eric Sunshine <sunshine@sunshineco.com>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/apply.c | 23 ++++++++++++++---------\n>  1 file changed, 14 insertions(+), 9 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index ae068e7..e133033 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -4522,6 +4522,19 @@ 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> +\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> +\n>  int cmd_apply(int argc, const char **argv, const char *prefix_)\n>  {\n>  \tint i;\n> @@ -4603,15 +4616,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> -\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> +\tinit_apply_state(&state, prefix_);\n>  \n>  \targc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n>  \t\t\tapply_usage, 0);\n"},{"id":"286355","messageId":"xmqq1t57f54n.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-11-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 10/94] builtin/apply: move 'unidiff_zero' global into 'struct apply_state'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:28:08Z","receivedAt":"2016-05-12T19:28:08Z","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> To libify the apply functionality the 'unidiff_zero' variable should\n> not be static and global to the file. Let's move it into\n> 'struct apply_state'.\n>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n\nLooks correct; I would have expected from the flow of thought in the\nseries that p_value and linenr that were already mentioned would be\nthe first two to be put in this, but that would have to wait until\nmore functions are taught to pass the state around, so this ordering\nwould probably be fine.\n\n>  builtin/apply.c | 42 ++++++++++++++++++++++++------------------\n>  1 file changed, 24 insertions(+), 18 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index e133033..44ae95d 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -24,6 +24,8 @@\n>  struct apply_state {\n>  \tconst char *prefix;\n>  \tint prefix_length;\n> +\n> +\tint unidiff_zero;\n>  };\n>  \n>  /*\n> @@ -37,7 +39,6 @@ struct apply_state {\n>   */\n>  static int newfd = -1;\n>  \n> -static int unidiff_zero;\n>  static int state_p_value = 1;\n>  static int p_value_known;\n>  static int check_index;\n> @@ -2694,7 +2695,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> @@ -2836,7 +2838,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> @@ -2844,7 +2846,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> @@ -3067,7 +3069,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> @@ -3080,7 +3082,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> @@ -3388,8 +3390,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> @@ -3415,7 +3420,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> @@ -3459,7 +3464,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> @@ -3467,9 +3473,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> @@ -3717,7 +3723,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> @@ -3816,13 +3822,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> @@ -3832,7 +3838,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> @@ -4597,7 +4603,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"},{"id":"286356","messageId":"xmqqwpmzdqe8.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-17-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 16/94] builtin/apply: move 'update_index' global into 'struct apply_state'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:31:43Z","receivedAt":"2016-05-12T19:31:43Z","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> To libify the apply functionality the 'update_index' variable should\n> not be static and global to the file. Let's move it into\n> 'struct apply_state'.\n>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/apply.c | 45 ++++++++++++++++++++++++++-------------------\n>  1 file changed, 26 insertions(+), 19 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index 97af6ea..635a9ff 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -39,6 +39,7 @@ struct apply_state {\n>  \tint check_index;\n>  \n>  \tint unidiff_zero;\n> +\tint update_index;\n\nThis should sit right next to check_index, I would think.\n\nOtherwise looks correct.\n"},{"id":"286357","messageId":"xmqqshxndqby.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-19-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 18/94] builtin/apply: move 'cached' global into 'struct apply_state'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:33:05Z","receivedAt":"2016-05-12T19:33:05Z","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> To libify the apply functionality the 'cached' variable should\n> not be static and global to the file. Let's move it into\n> 'struct apply_state'.\n>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/apply.c | 37 +++++++++++++++++++++----------------\n>  1 file changed, 21 insertions(+), 16 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index 8791b28..09af5dc 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -30,6 +30,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\nAgain, this should sit right next to update_index and check_index.\n\nOther than that, this step looks correct.\n"},{"id":"286358","messageId":"xmqqoa8bdpym.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-23-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 22/94] builtin/apply: move 'threeway' global into 'struct apply_state'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:41:05Z","receivedAt":"2016-05-12T19:41:05Z","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> To libify the apply functionality the 'threeway' variable should\n> not be static and global to the file. Let's move it into\n> 'struct apply_state'.\n>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/apply.c | 14 +++++++-------\n>  1 file changed, 7 insertions(+), 7 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index 6216723..3650922 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -40,6 +40,7 @@ struct apply_state {\n>  \tint numstat;\n>  \n>  \tint summary;\n> +\tint threeway;\n\nThis makes threeway look as if it is one of the cosmetic options\nlike stat/numstat/summary, doesn't it?  If anything, the blank\nbetween numstat and summary should be moved below summary.  I'd\ngroup knobs that affect \"what is affected (check, check_index,\ncached, etc.)\", \"how the application is done (allow-overlap,\nthreeway, in-reverse, etc.)\" and \"cosmetics\" and place the ones in\nthe same group next to each other.\n"},{"id":"286359","messageId":"xmqqk2izdpts.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-34-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 33/94] builtin/apply: move 'p_value_known' global into 'struct apply_state'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:43:59Z","receivedAt":"2016-05-12T19:43:59Z","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> To libify the apply functionality the 'p_value_known' variable should\n> not be static and global to the file. Let's move it into\n> 'struct apply_state'.\n\nThis and p_value belong together, I would think, so this can be\nsquashed with 32/94 if the series is to be rerolled (this alone is\nnot a reason to reroll the series, though).\n\n>\n> Reviewed-by: Stefan Beller <sbeller@google.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/apply.c | 9 ++++-----\n>  1 file changed, 4 insertions(+), 5 deletions(-)\n>\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index 4e476d5..30eea9c 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -63,13 +63,12 @@ struct apply_state {\n>  \tint line_termination;\n>  \n>  \tint p_value;\n> +\tint p_value_known;\n>  \tunsigned int p_context;\n>  };\n>  \n>  static int newfd = -1;\n>  \n> -static int p_value_known;\n> -\n>  static const char * const apply_usage[] = {\n>  \tN_(\"git apply [<options>] [<patch>...]\"),\n>  \tNULL\n> @@ -882,14 +881,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> @@ -4595,7 +4594,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"},{"id":"286360","messageId":"xmqqfutndpm3.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-41-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 40/94] builtin/apply: move 'ws_error_action' into 'struct apply_state'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:48:36Z","receivedAt":"2016-05-12T19:48:36Z","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>  struct apply_state {\n>  \tconst char *prefix;\n>  \tint prefix_length;\n> @@ -71,6 +78,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\nIt is very good that these whitespace-error related things are\nsitting next to each other.  I do not think the extra blank line is\nwarranted, though.\n\nIf anything, I'd say error-action should come at the beginning (as\nit is an end-user input that is set before the processing happens),\nand other three are states (that get new values after processing is\ndone) that should be listed after, to preserve the rough\nchronological order the variables are used (which translates to the\norder the readers need to become aware of and understand these\nvariables).\n"},{"id":"286361","messageId":"xmqqbn4bdp8f.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"20160511131745.2914-49-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T19:56:48Z","receivedAt":"2016-05-12T19:56:48Z","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> This is just a small cleanup.\n\n... which may have been better happened at 09/94.\n\nUp to this point, the conversion looks quite sensible, even though I\nthink the organization of fields in apply_state do not look logical.\n"},{"id":"286370","messageId":"CAP8UFD0XpEjVujeak3CyKFKHYnjKc+g_63EbNxRexm1oaRheZw@mail.gmail.com","threadId":"42281","inReplyTo":"xmqqr3d7f68l.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-12T20:05:54Z","receivedAt":"2016-05-12T20:05:54Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, May 12, 2016 at 9:04 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> As Christian said in 00/94, this probably needs to go in steps, as I\n> do not think anybody wants to review fouteen rounds of 90+ patch\n> series.  I thought the early 40+ patches in the series were at least\n> cursory reviewed already?\n\nYeah, Stefan said he was ok to give his Reviewed-by to v1 patches 01\nto 47 and they haven't changed much from v1 to v2.\n\nHere is the diff for those patches:\n\n> git diff 57be628 66c994d\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 787426f..67c64a5 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -67,13 +67,15 @@ struct apply_state {\n        /* --numstat does numeric diffstat, and doesn't actually apply */\n        int numstat;\n\n-       const char *fake_ancestor;\n-\n        int summary;\n-\n        int threeway;\n-\n        int no_add;\n+       const char *fake_ancestor;\n+       const char *patch_input_file;\n+       struct string_list limit_by_name;\n+       int has_include;\n+       struct strbuf root;\n+       struct string_list symlink_changes;\n\n        /*\n         *  --check turns on checking that the working tree matches the\n@@ -85,11 +87,8 @@ struct apply_state {\n        int check_index;\n\n        int unidiff_zero;\n-\n        int update_index;\n-\n        int unsafe_paths;\n-\n        int line_termination;\n\n        /*\n@@ -113,19 +112,10 @@ struct apply_state {\n         */\n        struct string_list fn_table;\n\n-       struct string_list symlink_changes;\n-\n        int p_value;\n        int p_value_known;\n        unsigned int p_context;\n\n-       const char *patch_input_file;\n-\n-       struct string_list limit_by_name;\n-       int has_include;\n-\n-       struct strbuf root;\n-\n        const char *whitespace_option;\n        int whitespace_error;\n        int squelch_whitespace_errors;\n@@ -1626,7 +1616,7 @@ static void record_ws_error(struct apply_state *state,\n                            unsigned result,\n                            const char *line,\n                            int len,\n-                           int l_nr)\n+                           int linenr)\n {\n        char *err;\n\n@@ -1640,7 +1630,7 @@ static void record_ws_error(struct apply_state *state,\n\n        err = whitespace_error_string(result);\n        fprintf(stderr, \"%s:%d: %s.\\n%.*s\\n\",\n-               state->patch_input_file, l_nr, err, len, line);\n+               state->patch_input_file, linenr, err, len, line);\n        free(err);\n }\n\n@@ -2445,7 +2435,7 @@ static int match_fragment(struct apply_state *state,\n                          int match_beginning, int match_end)\n {\n        int i;\n-       char *fixed_buf, *orig, *target;\n+       char *fixed_buf, *buf, *orig, *target;\n        struct strbuf fixed;\n        size_t fixed_len, postlen;\n        int preimage_limit;\n@@ -2506,7 +2496,6 @@ static int match_fragment(struct apply_state *state,\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@@ -4670,10 +4659,10 @@ static int option_parse_directory(const struct\noption *opt,\n        return 0;\n }\n\n-static void init_apply_state(struct apply_state *state, const char *prefix_)\n+static void init_apply_state(struct apply_state *state, const char *prefix)\n {\n        memset(state, 0, sizeof(*state));\n-       state->prefix = prefix_;\n+       state->prefix = prefix;\n        state->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n        state->apply = 1;\n        state->line_termination = '\\n';\n"},{"id":"286372","messageId":"CAP8UFD02iZ6fszG-T2xjajyjHwOSXbwtV07n7s2hVW2o-LVusg@mail.gmail.com","threadId":"42281","inReplyTo":"xmqq1t57f54n.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 10/94] builtin/apply: move 'unidiff_zero' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-12T20:18:57Z","receivedAt":"2016-05-12T20:18:57Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, May 12, 2016 at 9:28 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> To libify the apply functionality the 'unidiff_zero' variable should\n>> not be static and global to the file. Let's move it into\n>> 'struct apply_state'.\n>>\n>> Reviewed-by: Stefan Beller <sbeller@google.com>\n>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>> ---\n>\n> Looks correct; I would have expected from the flow of thought in the\n> series that p_value and linenr that were already mentioned would be\n> the first two to be put in this, but that would have to wait until\n> more functions are taught to pass the state around, so this ordering\n> would probably be fine.\n\nYeah, if the patches that put p_value and linenr into 'struct\napply_state' were earlier in the series, they would have to pass the\nstate around to a lot more functions, so they would have been very\nbig.\n"},{"id":"286394","messageId":"CAP8UFD1VYW6+T_oTHJbemUhi8MPrMseaObWgoy0Xou=VCoKt-A@mail.gmail.com","threadId":"42281","inReplyTo":"xmqqoa8bdpym.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 22/94] builtin/apply: move 'threeway' global into 'struct apply_state'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-12T20:26:34Z","receivedAt":"2016-05-12T20:26:34Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, May 12, 2016 at 9:41 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> To libify the apply functionality the 'threeway' variable should\n>> not be static and global to the file. Let's move it into\n>> 'struct apply_state'.\n>>\n>> Reviewed-by: Stefan Beller <sbeller@google.com>\n>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>> ---\n>>  builtin/apply.c | 14 +++++++-------\n>>  1 file changed, 7 insertions(+), 7 deletions(-)\n>>\n>> diff --git a/builtin/apply.c b/builtin/apply.c\n>> index 6216723..3650922 100644\n>> --- a/builtin/apply.c\n>> +++ b/builtin/apply.c\n>> @@ -40,6 +40,7 @@ struct apply_state {\n>>       int numstat;\n>>\n>>       int summary;\n>> +     int threeway;\n>\n> This makes threeway look as if it is one of the cosmetic options\n> like stat/numstat/summary, doesn't it?  If anything, the blank\n> between numstat and summary should be moved below summary.\n\nThere is a blank because there is a comment on the line before\nnumstat. The result looks like this:\n\n    /* --cached updates only the cache without ever touching the\nworking tree. */\n    int cached;\n\n    /* --stat does just a diffstat, and doesn't actually apply */\n    int diffstat;\n\n    /* --numstat does numeric diffstat, and doesn't actually apply */\n    int numstat;\n\n    int summary;\n    int threeway;\n    int no_add;\n\n\n>  I'd\n> group knobs that affect \"what is affected (check, check_index,\n> cached, etc.)\", \"how the application is done (allow-overlap,\n> threeway, in-reverse, etc.)\" and \"cosmetics\" and place the ones in\n> the same group next to each other.\n\nOk, I will try to group knobs like that, but the comments tend to\nbreak the groups.\n"},{"id":"286395","messageId":"xmqq37pndn2x.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"xmqqbn4bdp8f.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T20:43:18Z","receivedAt":"2016-05-12T20:43:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Up to this point, the conversion looks quite sensible, even though I\n> think the organization of fields in apply_state do not look logical.\n\nI'd stop here for now, as everything before this step looks\nuncontroversial.  Anybody whose tasked to move the global state for\nthese variables into a structure would reach the samestate after\napplying these 48 patches, modulo minor differences in the way the\ncomments would say things, how the patches are split and how the\nfields in apply_state() are organized.\n\nOne thing that is missing is a counterpart of init_apply_state().\nIn the early part of patches where it added only \"const char *\"\nborrowed from the caller and fields of intregral type, the lack of\nclear_apply_state() did not mattter, but with a few fields with\n\"string_list\" type, anybody who want to make repeated call into the\napply machinery would want a way to release the resource the\nstructure holds.\n\nBecause 49/94 is a step to add an unfreeable resource, this is a\ngood place to stop and then add the clean_apply_state() before that\nhappens, I would think.  After that, I think both the contributor\nand the reviewers would benefit if these early patches are merged\nearly without waiting for the review of the remainder.\n\nThanks.\n"},{"id":"286403","messageId":"xmqqeg97c6qo.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"CAP8UFD1VYW6+T_oTHJbemUhi8MPrMseaObWgoy0Xou=VCoKt-A@mail.gmail.com","subject":"Re: [PATCH v2 22/94] builtin/apply: move 'threeway' global into 'struct apply_state'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T21:21:35Z","receivedAt":"2016-05-12T21:21:35Z","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> Ok, I will try to group knobs like that, but the comments tend to\n> break the groups.\n\nBy keeping the comment on a single field short, and reserve comment\noccupying its own line(s) to comment on group, you can do\n\n\t/* These control what gets looked at and modified */\n        int\tapply;\t/* this is not a dry-run */\n        int\tcheck_index; /* preimage must match the indexed version */\n        int\tcached; /* apply to the index only */\n\n\t/* These control cosmetic aspect of the output */\n        int\tdiffstat; /* show diffstat */\n        int\tnumstat; /* numerical stat */\n        int\tsummary; /* report creation, deletion, etc. */\n"},{"id":"286430","messageId":"alpine.DEB.2.20.1605130820160.4092@virtualbox","threadId":"42281","inReplyTo":"20160511131745.2914-1-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-13T06:32:35Z","receivedAt":"2016-05-13T06:32:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Chris,\n\nOn Wed, 11 May 2016, Christian Couder wrote:\n\n> I consider that the apply functionality is properly libified before\n> these patches, and that they should be in a separate series, but\n> unfortunately using the libified apply in \"git am\" unmasks the fact that\n> \"git am\", since it was a shell script, has been silencing the apply\n> functionality by \"futzing with file descriptors\". And unfortunately this\n> makes some reviewers unhappy.\n\nIt is a misrepresentation to claim that this makes some reviewers unhappy.\nSpeaking for myself, I am very happy. Despite having had to point out\nthat the previous iteration of this patch series had a serious flaw.\n\nIt is also incorrect to say that the shell script had been \"futzing with\nthe file descriptors\". You see, the shell script's *own* file descriptors\nhad been left completely unaffected by the redirection of the spawned\nprocess' output. That was perfectly fine a thing to do, even if it\npossibly hid fatal errors. Shell scripts are simply very limiting. The\nproblem was introduced by v1 of this patch series, which changed *the\ncaller's file descriptors* back and forth simply because the called code\nno longer runs in a separate process. And *that* was, and is, improper.\n\n> By the way there are no tests yet for this new feature, and I am not\n> sure at all that \"--silent\" and \"be_silent\" are good names.\n\nIf you want to follow existing code's example, we typically call this\noption \"quiet\".\n\n> Sorry if this patch series is long. I can split it into two or more\n> series if it is prefered.\n\nIt is preferred. Much.\n\nCiao,\nDscho\n\nP.S.: Even two ~40-strong patch series are *really* painful to review. I\nbelieve you can do a much better job at cutting this monster down into\npalatable chunks, each with its own sweet little story.\n"},{"id":"286480","messageId":"CAP8UFD2fSW0nds7myfb_09c+EaCdn6+1OqsNEzfY2rVTeA5TAw@mail.gmail.com","threadId":"42281","inReplyTo":"alpine.DEB.2.20.1605130820160.4092@virtualbox","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-13T18:49:23Z","receivedAt":"2016-05-13T18:49:23Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Hi Dscho,\n\nOn Fri, May 13, 2016 at 8:32 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Chris,\n>\n> On Wed, 11 May 2016, Christian Couder wrote:\n>\n>> I consider that the apply functionality is properly libified before\n>> these patches, and that they should be in a separate series, but\n>> unfortunately using the libified apply in \"git am\" unmasks the fact that\n>> \"git am\", since it was a shell script, has been silencing the apply\n>> functionality by \"futzing with file descriptors\". And unfortunately this\n>> makes some reviewers unhappy.\n>\n> It is a misrepresentation to claim that this makes some reviewers unhappy.\n> Speaking for myself, I am very happy. Despite having had to point out\n> that the previous iteration of this patch series had a serious flaw.\n>\n> It is also incorrect to say that the shell script had been \"futzing with\n> the file descriptors\". You see, the shell script's *own* file descriptors\n> had been left completely unaffected by the redirection of the spawned\n> process' output. That was perfectly fine a thing to do, even if it\n> possibly hid fatal errors. Shell scripts are simply very limiting. The\n> problem was introduced by v1 of this patch series, which changed *the\n> caller's file descriptors* back and forth simply because the called code\n> no longer runs in a separate process. And *that* was, and is, improper.\n\nI think we should just agree that we disagree on what we think the v1\nwas doing and move on to v2.\n\n>> By the way there are no tests yet for this new feature, and I am not\n>> sure at all that \"--silent\" and \"be_silent\" are good names.\n>\n> If you want to follow existing code's example, we typically call this\n> option \"quiet\".\n\nIn the documentation there is:\n\nDocumentation/git-am.txt:--quiet::\nDocumentation/git-am.txt:       Be quiet. Only print error messages.\nDocumentation/git-branch.txt:--quiet::\nDocumentation/git-branch.txt:   Be more quiet when creating or\ndeleting a branch, suppressing\nDocumentation/git-branch.txt-   non-error messages.\nDocumentation/git-checkout-index.txt:--quiet::\nDocumentation/git-checkout-index.txt:   be quiet if files exist or are\nnot in the index\nDocumentation/git-checkout.txt:--quiet::\nDocumentation/git-checkout.txt- Quiet, suppress feedback messages.\nDocumentation/git-clean.txt:--quiet::\nDocumentation/git-clean.txt:    Be quiet, only report errors, but not\nthe files that are\nDocumentation/git-clean.txt-    successfully removed.\nDocumentation/git-clone.txt--q::\nDocumentation/git-clone.txt:    Operate quietly.  Progress is not\nreported to the standard\nDocumentation/git-clone.txt-    error stream.\nocumentation/git-commit.txt:--quiet::\nDocumentation/git-commit.txt-   Suppress commit summary message.\nDocumentation/git-fast-import.txt:--quiet::\nDocumentation/git-fast-import.txt-      Disable all non-fatal output,\nmaking fast-import silent when it\n...\n\nSo it looks to me that --quiet means something like \"don't tell the\nstory of your life, but in case of problem you are allowed to\ncomplain\". In other word --quiet generally doesn't suppress error\nmessages from error() or die().\n\nOn the contrary the new feature I tentatively called --silent does\nsuppress all output including error messages from error().\n\nNow if people think that it is not worth making a difference between\nthe different behaviors, then I am ok to rename it --quiet, though I\nwonder what will happen if people later want a --quiet that does only\nwhat --quiet usually does to the other commands.\n\n>> Sorry if this patch series is long. I can split it into two or more\n>> series if it is prefered.\n>\n> It is preferred. Much.\n\nOk, I will split it then.\n\nThanks,\nChristian.\n"},{"id":"286481","messageId":"CAP8UFD2i9rDi4K=2_hKmEwjtCgnkP6Bi6gFMymPgu2t-qsdA6g@mail.gmail.com","threadId":"42281","inReplyTo":"xmqqbn4bdp8f.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-13T19:42:35Z","receivedAt":"2016-05-13T19:42:35Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, May 12, 2016 at 9:56 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> This is just a small cleanup.\n>\n> ... which may have been better happened at 09/94.\n\nOk, I will squash it in 09/94.\n"},{"id":"286482","messageId":"CAP8UFD05JuxG21MAV0wSYz+Vzqb8-unjW-rOSJ_c9YWWOoTTSQ@mail.gmail.com","threadId":"42281","inReplyTo":"xmqq37pndn2x.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-13T19:45:50Z","receivedAt":"2016-05-13T19:45:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, May 12, 2016 at 10:43 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Up to this point, the conversion looks quite sensible, even though I\n>> think the organization of fields in apply_state do not look logical.\n>\n> I'd stop here for now, as everything before this step looks\n> uncontroversial.  Anybody whose tasked to move the global state for\n> these variables into a structure would reach the samestate after\n> applying these 48 patches, modulo minor differences in the way the\n> comments would say things, how the patches are split and how the\n> fields in apply_state() are organized.\n>\n> One thing that is missing is a counterpart of init_apply_state().\n> In the early part of patches where it added only \"const char *\"\n> borrowed from the caller and fields of intregral type, the lack of\n> clear_apply_state() did not mattter, but with a few fields with\n> \"string_list\" type, anybody who want to make repeated call into the\n> apply machinery would want a way to release the resource the\n> structure holds.\n>\n> Because 49/94 is a step to add an unfreeable resource, this is a\n> good place to stop and then add the clean_apply_state() before that\n> happens, I would think.  After that, I think both the contributor\n> and the reviewers would benefit if these early patches are merged\n> early without waiting for the review of the remainder.\n\nOk, I will add add the clean_apply_state() and resend the patches up\nto that point soon, so that they can be merged early.\n\nThanks,\nChristian.\n"},{"id":"286525","messageId":"alpine.DEB.2.20.1605140807310.4092@virtualbox","threadId":"42281","inReplyTo":"CAP8UFD2fSW0nds7myfb_09c+EaCdn6+1OqsNEzfY2rVTeA5TAw@mail.gmail.com","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-14T06:26:40Z","receivedAt":"2016-05-14T06:26:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Chris,\n\nOn Fri, 13 May 2016, Christian Couder wrote:\n\n> On Fri, May 13, 2016 at 8:32 AM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Wed, 11 May 2016, Christian Couder wrote:\n> >\n> >> I consider that the apply functionality is properly libified before\n> >> these patches, and that they should be in a separate series, but\n> >> unfortunately using the libified apply in \"git am\" unmasks the fact\n> >> that \"git am\", since it was a shell script, has been silencing the\n> >> apply functionality by \"futzing with file descriptors\". And\n> >> unfortunately this makes some reviewers unhappy.\n> >\n> > It is a misrepresentation to claim that this makes some reviewers\n> > unhappy.  Speaking for myself, I am very happy. Despite having had to\n> > point out that the previous iteration of this patch series had a\n> > serious flaw.\n> >\n> > It is also incorrect to say that the shell script had been \"futzing\n> > with the file descriptors\". You see, the shell script's *own* file\n> > descriptors had been left completely unaffected by the redirection of\n> > the spawned process' output. That was perfectly fine a thing to do,\n> > even if it possibly hid fatal errors. Shell scripts are simply very\n> > limiting. The problem was introduced by v1 of this patch series, which\n> > changed *the caller's file descriptors* back and forth simply because\n> > the called code no longer runs in a separate process. And *that* was,\n> > and is, improper.\n> \n> I think we should just agree that we disagree on what we think the v1\n> was doing and move on to v2.\n\nIt is obvious that you want to disagree. But that is counterproductive.\n\nIt is important to keep in mind, and needs to be remembered in future\nlibification efforts, that extra care is required when we no longer spawn\na separate process: you no longer have the option to change global state\n*just* for the called process.\n\nThis is very true when redirecting (global) file descriptors. I struggle\nwith this myself in the rebase--helper branch, so it is not only you who\nhas to face, and address, this issue.\n\nThe same goes for die(), too, of course. And for statically allocated\nmemory. And even worse: when all of a sudden reusing static lockfile\nstructs. And, and, and. The list goes on.\n\nIt really comes back at us that we originally simple did not care about\ncleaning up after us \"because it is a short-lived process, anyway\".\n\nThe thing is: this is not at all the philosophical discussion as which\nyour comment tries to color it. We *have* to address these issues when\nlibifying code. Yes, it's hard. Yes, it's tedious. Yes, I also want to\nbitch about it.\n\nAnd yes, it must be done.\n\n> >> By the way there are no tests yet for this new feature, and I am not\n> >> sure at all that \"--silent\" and \"be_silent\" are good names.\n> >\n> > If you want to follow existing code's example, we typically call this\n> > option \"quiet\".\n> \n> In the documentation there is: [... snip ...]\n> ...\n> \n> So it looks to me that --quiet means something like \"don't tell the\n> story of your life, but in case of problem you are allowed to\n> complain\". In other word --quiet generally doesn't suppress error\n> messages from error() or die().\n\nRight.\n\nAnd if you care to take a step back, this is most likely what we want in\nlibified code.\n\nModulo die(), of course!\n\n> On the contrary the new feature I tentatively called --silent does\n> suppress all output including error messages from error().\n\nAnd what would be the point of that? Now that we are libifying code, in\ncontrast to the spawned-process approach, we *can* discern between \"prints\nto stderr\" and \"displays an error\". I'd wager that you won't find any\nerror() call in the code path that we want to silence.\n\n> Now if people think that it is not worth making a difference between the\n> different behaviors, then I am ok to rename it --quiet, though I wonder\n> what will happen if people later want a --quiet that does only what\n> --quiet usually does to the other commands.\n\nYou know, I get the distinct impression that you do not want my feedback\nbecause you always want \"people\" to agree with my assessment. I hoped that\nmy arguments would make sense, but I guess I should spend my time\ndifferently.\n\n> >> Sorry if this patch series is long. I can split it into two or more\n> >> series if it is prefered.\n> >\n> > It is preferred. Much.\n> \n> Ok, I will split it then.\n\nThank you. Maybe you take me off of the Cc: list, too?\n\nThanks,\nDscho\n"},{"id":"286528","messageId":"CAP8UFD376guRRPpMVjC36K0dvWy17xdaHvV1WoRjMaNpdp0bqQ@mail.gmail.com","threadId":"42281","inReplyTo":"alpine.DEB.2.20.1605140807310.4092@virtualbox","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-14T09:19:20Z","receivedAt":"2016-05-14T09:19:20Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sat, May 14, 2016 at 8:26 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n\n[...]\n\n>> >> By the way there are no tests yet for this new feature, and I am not\n>> >> sure at all that \"--silent\" and \"be_silent\" are good names.\n>> >\n>> > If you want to follow existing code's example, we typically call this\n>> > option \"quiet\".\n>>\n>> In the documentation there is: [... snip ...]\n>> ...\n>>\n>> So it looks to me that --quiet means something like \"don't tell the\n>> story of your life, but in case of problem you are allowed to\n>> complain\". In other word --quiet generally doesn't suppress error\n>> messages from error() or die().\n>\n> Right.\n>\n> And if you care to take a step back, this is most likely what we want in\n> libified code.\n\nIn the previous discussion, Junio asked:\n\n\"How far can you go with just set-error-routine?  Are there things,\nother than the file descriptors, that you need to futz with in order\nto covert that \"we'd fallback, so this early round must be silent\"\ncodepath?\"\n\nSo it looks to me that the goal is to have something that replicate\nthe current behavior, which is to not even display messages from\nerror().\n\n[...]\n\n>> >> Sorry if this patch series is long. I can split it into two or more\n>> >> series if it is prefered.\n>> >\n>> > It is preferred. Much.\n>>\n>> Ok, I will split it then.\n>\n> Thank you. Maybe you take me off of the Cc: list, too?\n\nOk I will do that.\n"},{"id":"286542","messageId":"xmqqy47c7awg.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"CAP8UFD05JuxG21MAV0wSYz+Vzqb8-unjW-rOSJ_c9YWWOoTTSQ@mail.gmail.com","subject":"Re: [PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-14T18:27:27Z","receivedAt":"2016-05-14T18:27:27Z","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> On Thu, May 12, 2016 at 10:43 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>>> Up to this point, the conversion looks quite sensible, even though I\n>>> think the organization of fields in apply_state do not look logical.\n>>\n>> I'd stop here for now, as everything before this step looks\n>> uncontroversial.  Anybody whose tasked to move the global state for\n>> these variables into a structure would reach the samestate after\n>> applying these 48 patches, modulo minor differences in the way the\n>> comments would say things, how the patches are split and how the\n>> fields in apply_state() are organized.\n>>\n>> One thing that is missing is a counterpart of init_apply_state().\n>> In the early part of patches where it added only \"const char *\"\n>> borrowed from the caller and fields of intregral type, the lack of\n>> clear_apply_state() did not mattter, but with a few fields with\n>> \"string_list\" type, anybody who want to make repeated call into the\n>> apply machinery would want a way to release the resource the\n>> structure holds.\n>>\n>> Because 49/94 is a step to add an unfreeable resource, this is a\n>> good place to stop and then add the clean_apply_state() before that\n>> happens, I would think.  After that, I think both the contributor\n>> and the reviewers would benefit if these early patches are merged\n>> early without waiting for the review of the remainder.\n>\n> Ok, I will add add the clean_apply_state() and resend the patches up\n> to that point soon, so that they can be merged early.\n\nTwo more comments:\n\n - Just like the change between v1 and v2, if we were to introduce\n   clear_apply_state(), it would be nicer if it were done early in\n   the series, ideally at the same time as init_apply_state() gets\n   introduced, or at least no later than the first field that holds\n   resource that needs releasing is added.\n\n - I didn't double check if 50 and later still had changes that\n   belong to this \"early batch that moves things into a struct\" (aka\n   cc/apply-introduce-state) topic, as I stopped at 49 and saw the\n   need for clear_apply_state().  So 48 may not be the ideal place\n   to stop.  From a cursory read of their titles, perhaps 49, 50, 56\n   and possibly 60 should be in this early series?  While 60 does\n   sound like an immediate follow-up to 09/94, it depends on a few\n   \"die elimination\" changes, so I do NOT think it must be in the\n   early batch.\n"},{"id":"286543","messageId":"xmqqwpmw7aow.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"CAP8UFD376guRRPpMVjC36K0dvWy17xdaHvV1WoRjMaNpdp0bqQ@mail.gmail.com","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-14T18:31:59Z","receivedAt":"2016-05-14T18:31:59Z","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>>> So it looks to me that --quiet means something like \"don't tell the\n>>> story of your life, but in case of problem you are allowed to\n>>> complain\". In other word --quiet generally doesn't suppress error\n>>> messages from error() or die().\n>>\n>> Right.\n>>\n>> And if you care to take a step back, this is most likely what we want in\n>> libified code.\n>\n> In the previous discussion, Junio asked:\n>\n> \"How far can you go with just set-error-routine?  Are there things,\n> other than the file descriptors, that you need to futz with in order\n> to covert that \"we'd fallback, so this early round must be silent\"\n> codepath?\"\n>\n> So it looks to me that the goal is to have something that replicate\n> the current behavior, which is to not even display messages from\n> error().\n\nNote that I was not endorsing the approach to use set-error-routine,\none of whose downside is that it is easy to silence everything\nunconditionally.  Between --quiet/--silent, I wasn't making any\nchoice, as I hadn't even formed an opinion back when I wrote it.\n\nI was merely asking \"is use of set-error-routine the worst thing you\nneed to do, or do you need to do anything more gross?\", half\nanticipating \"no, it turns out that I need to longjmp(3) from my\ndie-routine to come back from deep in the existing code because I do\nnot think I'd bother propagating the error status all the way along\nthe call stack\", at which point my response would have been \"Ugh,\nuse of set-error-routine to avoid properly refactoring, even if we\nassume it is OK to squelch the errors unconditionally, is bad\nenough.  If you need to longjmp(3), that's no longer a libification.\nYou are better off using the run_command() interface to give the\ncaller and the callee a proper isolation\".\n\nLibification is not just \"now it runs inside a single process\" at\nall.  It is more about \"it has proper abstraction and separation so\nthat callers have _more_ control than they used to (compared to\ninteracting with a spawned process) while retaining the control of\ntheir own environment\".\n\nAnd as this thread showed, when turning an implementation that uses\nrun-command with program's standard error sent to /dev/null into a\n\"libified\" implementation, we _gain_ a possibility to be more\nselective in what we silence.  I think that exactly falls into\n\"callers have more control\" category of libification benefit.\n\nQuite honestly, I was sort of surprised by the quality of the\nargument for proper libification Dscho has been making in this\nthread, and that was why I didn't say much here.\n\nHaving said all that, as to --quiet/--silent, another way to surface\nthe \"even more quiet\" used is with \"-q -q\" (i.e. multiple levels of\nquietness).  I am just saying this for the record without suggesting\nit is better or worse suited for this case than what has been\ndiscussed.\n\nIn any case, I do see the need for what your --silent option does\ninternally when a caller like \"am\" calls into the libified \"apply\"\nmachinery.  When we _know_ we will run a \"fallback\" invocation after\nan initial \"more strict\" apply attempt fails, we do want the initial\ninvocation to be totally silent, not even with any error message,\nbecause we know that it is sufficient to let the fallback invocation\nshow its error message (if it fails).  The fallback may even succeed\nin which case error messages from the initial invocation serves only\nas an explanation of the reason why we used fallback, which is not\ninteresting to the end user at all.\n\nI however do not see a reason why you need to expose that feature to\nthe users of \"git apply\".  So I am not sure if any of us care deeply\nthe choice among --silent, --quiet and -q -q.\n"},{"id":"286548","messageId":"CAP8UFD0GrSy9E5Yv9Bdbd8SK+Q8GgYW2jDC-iopzsajpA6BKsw@mail.gmail.com","threadId":"42281","inReplyTo":"xmqqwpmw7aow.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-14T19:37:43Z","receivedAt":"2016-05-14T19:37:43Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sat, May 14, 2016 at 8:31 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> I however do not see a reason why you need to expose that feature to\n> the users of \"git apply\".  So I am not sure if any of us care deeply\n> the choice among --silent, --quiet and -q -q.\n\nAbout that I wrote in initial email above:\n\n\"The last patch 94/94 adds a --silent command line option to git apply.\nThis is not necessary, but some scripts could perhaps use it, and it\ncould make it easier to test the new silent feature.\"\n\nI expose the feature in the last patch exactly because, if we don't\nwant to expose the feature, is is easy to do by just dropping the last\npatch.\nAnd I explain the reasons why it might be a good idea to expose the\nfeature, but I am also ok with just dropping the patch.\n"},{"id":"286597","messageId":"xmqq1t536une.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"CAP8UFD0GrSy9E5Yv9Bdbd8SK+Q8GgYW2jDC-iopzsajpA6BKsw@mail.gmail.com","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-15T18:30:45Z","receivedAt":"2016-05-15T18:30:45Z","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> On Sat, May 14, 2016 at 8:31 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>\n>> I however do not see a reason why you need to expose that feature to\n>> the users of \"git apply\".  So I am not sure if any of us care deeply\n>> the choice among --silent, --quiet and -q -q.\n>\n> About that I wrote in initial email above:\n> ...\n\nBecause you are not bound to stick to what you thought before the\ndiscussion, what you wrote before everybody commented to improve\nyour proposal does not really matter.  Otherwise, the time they\nspent would be wasted.  What matters more is what conclusion you\ndrew after having input from others.\n\n\"That --silent is optional and cannot decide if I want to have the\noption was what I said at the beginning\" does not help the\ndiscussion very much at this point.  People know that you couldn't\ndecide back then, and that is why they hopefully helped you to get\ncloser to deciding by discussing the series.\n\n\"OK, I now think we don't need 'apply --silent' because ..., so I'll\ndrop it\" or \"I still think we want 'apply --silent' because..., so\nI'll keep it\", followed by \"thanks for discussing and helping\" would\nbe a more appropriate answer, whichever conclusion you have drawn.\n\n\"Hmm, I still cannot decide.\" is also fine, by the way.\n"},{"id":"286636","messageId":"CAPig+cQrLZiwZm34+hFZXPmFGVtyPCvCEv4TwsTeL__cfzuORA@mail.gmail.com","threadId":"42281","inReplyTo":"20160511131745.2914-53-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 52/94] builtin/apply: read_patch_file() return -1 instead of die()ing","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T01:56:30Z","receivedAt":"2016-05-16T01:56:30Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> To libify `git apply` functionality we have to signal errors to the\n> caller instead of die()ing. Let's do that by using error() instead\n> of die()ing in read_patch_file().\n>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> @@ -445,10 +445,10 @@ static void say_patch_name(FILE *output, const char *fmt, struct patch *patch)\n> -static void read_patch_file(struct strbuf *sb, int fd)\n> +static int read_patch_file(struct strbuf *sb, int fd)\n>  {\n>         if (strbuf_read(sb, fd, 0) < 0)\n> -               die_errno(\"git apply: failed to read\");\n> +               return error(\"git apply: failed to read: %s\", strerror(errno));\n\nWhen Duy's nd/error-errno series, which is in 'next', gets promoted to\n'master', then this could become:\n\n    return error_errno(...);\n\n>         /*\n>          * Make sure that we have some slop in the buffer\n> @@ -457,6 +457,7 @@ static void read_patch_file(struct strbuf *sb, int fd)\n>          */\n>         strbuf_grow(sb, SLOP);\n>         memset(sb->buf + sb->len, 0, SLOP);\n> +       return 0;\n>  }\n"},{"id":"286638","messageId":"CAPig+cQkKijp_Mg0Ho0wAFSxmLin0EPA_a5PwV9DaHkHLJKNMA@mail.gmail.com","threadId":"42281","inReplyTo":"20160511131745.2914-55-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 54/94] builtin/apply: make parse_chunk() return a negative integer on error","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T03:04:58Z","receivedAt":"2016-05-16T03:04:58Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> To libify `git apply` functionality we have to signal errors to the\n> caller instead of die()ing or exit()ing.\n>\n> To do that in a compatible manner with the rest of the error handling\n> in builtin/apply.c, find_header() should return -1 instead of calling\n> die() or exit().\n\nWhy is this talking about making find_header() return -1? Didn't that\nhappen in the previous patch?\n\n> As parse_chunk() is called only by apply_patch() which already\n> returns -1 when an error happened, let's make apply_patch() return -1\n> when parse_chunk() returns -1.\n>\n> If find_header() returns -2 because no patch header has been found, it\n> is ok for parse_chunk() to also return -2. If find_header() returns -1\n> because an error happened, it is ok for parse_chunk() to do the same.\n>\n> Helped-by: Eric Sunshine <sunshine@sunshineco.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> @@ -2176,8 +2176,9 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n>                  * empty to us here.\n>                  */\n>                 if ((state->apply || state->check) &&\n> -                   (!patch->is_binary && !metadata_changes(patch)))\n> -                       die(_(\"patch with only garbage at line %d\"), state->linenr);\n> +                   (!patch->is_binary && !metadata_changes(patch))) {\n> +                       return error(_(\"patch with only garbage at line %d\"), state->linenr);\n> +               }\n\nUnnecessary braces.\n\n>         }\n>\n>         return offset + hdrsize + patchsize;\n"},{"id":"286639","messageId":"CAPig+cS98guXbeRH6oW8n2tPAa3u=2MvSx1H5rixGKdGTrVJPg@mail.gmail.com","threadId":"42281","inReplyTo":"20160511131745.2914-57-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 56/94] apply: move 'struct apply_state' to apply.h","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T03:10:14Z","receivedAt":"2016-05-16T03:10:14Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> To libify `git apply` functionality we must make 'struct apply_state'\n> usable outside \"builtin/apply.c\".\n\nWhy is this patch plopped right in the middle of a bunch of other\npatches which are making functions return -1 rather than die()ing?\nSeems out of place.\n\n> Let's do that by creating a new \"apply.h\" and moving\n> 'struct apply_state' there.\n\nI could easily see this header introduced at a very early stage when\n'struct apply_state' itself is introduced, rather than introducing\n'struct apply_state' in builtin/apply.c and later moving it here.\n\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n"},{"id":"286640","messageId":"CAPig+cSWPYx9o-fnzXqUN4KR8h+15nBAX8CHhbiCxd5QcyOJLg@mail.gmail.com","threadId":"42281","inReplyTo":"20160511131745.2914-60-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 59/94] builtin/apply: move init_apply_state() to apply.c","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T03:16:18Z","receivedAt":"2016-05-16T03:16:18Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> To libify `git apply` functionality we must make init_apply_state()\n> usable outside \"builtin/apply.c\".\n>\n> Let's do that by moving it into a new \"apply.c\".\n\nSimilar to my comment about apply.h and 'struct apply_state', I can\neasily see apply.c introduced very early in the conversion. In fact,\nI'd imagine apply.c and apply.h being introduced by the same patch,\nwith that patch placing init_apply_state() in apply.c and 'struct\napply_state' in apply.h. However, I see that you're moving other\nfunctions, as well, which already existed in builtin/apply.c, so I\nguess that's why introduction of apply.c waited until this step.\n\n> Helped-by: Eric Sunshine <sunshine@sunshineco.com>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n> diff --git a/apply.c b/apply.c\n> @@ -0,0 +1,83 @@\n> +#include \"cache.h\"\n> +#include \"lockfile.h\"\n> +#include \"apply.h\"\n> +\n> +static void git_apply_config(void)\n> +{\n> +       git_config_get_string_const(\"apply.whitespace\", &apply_default_whitespace);\n> +       git_config_get_string_const(\"apply.ignorewhitespace\", &apply_default_ignorewhitespace);\n> +       git_config(git_default_config, NULL);\n> +}\n> +\n> +int parse_whitespace_option(struct apply_state *state, const char *option)\n> +{\n> +       if (!option) {\n> +               state->ws_error_action = warn_on_ws_error;\n> +               return 0;\n> +       }\n> +       if (!strcmp(option, \"warn\")) {\n> +               state->ws_error_action = warn_on_ws_error;\n> +               return 0;\n> +       }\n> +       if (!strcmp(option, \"nowarn\")) {\n> +               state->ws_error_action = nowarn_ws_error;\n> +               return 0;\n> +       }\n> +       if (!strcmp(option, \"error\")) {\n> +               state->ws_error_action = die_on_ws_error;\n> +               return 0;\n> +       }\n> +       if (!strcmp(option, \"error-all\")) {\n> +               state->ws_error_action = die_on_ws_error;\n> +               state->squelch_whitespace_errors = 0;\n> +               return 0;\n> +       }\n> +       if (!strcmp(option, \"strip\") || !strcmp(option, \"fix\")) {\n> +               state->ws_error_action = correct_ws_error;\n> +               return 0;\n> +       }\n> +       return error(_(\"unrecognized whitespace option '%s'\"), option);\n> +}\n> +\n> +int parse_ignorewhitespace_option(struct apply_state *state,\n> +                                 const char *option)\n> +{\n> +       if (!option || !strcmp(option, \"no\") ||\n> +           !strcmp(option, \"false\") || !strcmp(option, \"never\") ||\n> +           !strcmp(option, \"none\")) {\n> +               state->ws_ignore_action = ignore_ws_none;\n> +               return 0;\n> +       }\n> +       if (!strcmp(option, \"change\")) {\n> +               state->ws_ignore_action = ignore_ws_change;\n> +               return 0;\n> +       }\n> +       return error(_(\"unrecognized whitespace ignore option '%s'\"), option);\n> +}\n> +\n> +void init_apply_state(struct apply_state *state,\n> +                     const char *prefix,\n> +                     struct lock_file *lock_file)\n> +{\n> +       memset(state, 0, sizeof(*state));\n> +       state->prefix = prefix;\n> +       state->prefix_length = state->prefix ? strlen(state->prefix) : 0;\n> +       state->lock_file = lock_file ? lock_file : xcalloc(1, sizeof(*lock_file));\n> +       state->newfd = -1;\n> +       state->apply = 1;\n> +       state->line_termination = '\\n';\n> +       state->p_value = 1;\n> +       state->p_context = UINT_MAX;\n> +       state->squelch_whitespace_errors = 5;\n> +       state->ws_error_action = warn_on_ws_error;\n> +       state->ws_ignore_action = ignore_ws_none;\n> +       state->linenr = 1;\n> +       strbuf_init(&state->root, 0);\n> +\n> +       git_apply_config();\n> +       if (apply_default_whitespace && parse_whitespace_option(state, apply_default_whitespace))\n> +               exit(1);\n> +       if (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))\n> +               exit(1);\n> +}\n> +\n> diff --git a/apply.h b/apply.h\n> index aa11ea6..0f77f4d 100644\n> --- a/apply.h\n> +++ b/apply.h\n> @@ -112,4 +112,13 @@ struct apply_state {\n>         enum ws_ignore ws_ignore_action;\n>  };\n>\n> +extern int parse_whitespace_option(struct apply_state *state,\n> +                                  const char *option);\n> +extern int parse_ignorewhitespace_option(struct apply_state *state,\n> +                                        const char *option);\n> +\n> +extern void init_apply_state(struct apply_state *state,\n> +                            const char *prefix,\n> +                            struct lock_file *lock_file);\n> +\n>  #endif\n"},{"id":"286642","messageId":"CAPig+cQ7zqhyFW5jwX5fFNKB11=hgOrOvaD-pNckxEMxmvBcjg@mail.gmail.com","threadId":"42281","inReplyTo":"20160511131745.2914-61-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 60/94] apply: make init_apply_state() return -1 instead of exit()ing","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T03:37:57Z","receivedAt":"2016-05-16T03:37:57Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> To libify `git apply` functionality we have to signal errors to the\n> caller instead of exit()ing.\n>\n> To do that in a compatible manner with the rest of the error handling\n> in \"builtin/apply.c\", init_apply_state() should return -1 using\n> error() instead of calling exit().\n\nThis commit message seems to be lying. It says that the -1 comes from\nerror(), however, init_apply_state() just returns literal -1 in all\ncases.\n\nBy the way, mentioning \"return -1 using error()\" in all of these\ncommit messages (not just this one) may be overkill. The fact that\nthat side-effect of error() is being used in some of these cases is an\nimplementation detail which doesn't necessarily merit mention in the\ncommit message.\n\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n> diff --git a/apply.c b/apply.c\n> index 508ea64..1e2b802 100644\n> --- a/apply.c\n> +++ b/apply.c\n> @@ -55,9 +55,9 @@ int parse_ignorewhitespace_option(struct apply_state *state,\n>         return error(_(\"unrecognized whitespace ignore option '%s'\"), option);\n>  }\n>\n> -void init_apply_state(struct apply_state *state,\n> -                     const char *prefix,\n> -                     struct lock_file *lock_file)\n> +int init_apply_state(struct apply_state *state,\n> +                    const char *prefix,\n> +                    struct lock_file *lock_file)\n>  {\n>         memset(state, 0, sizeof(*state));\n>         state->prefix = prefix;\n> @@ -76,8 +76,9 @@ void init_apply_state(struct apply_state *state,\n>\n>         git_apply_config();\n>         if (apply_default_whitespace && parse_whitespace_option(state, apply_default_whitespace))\n> -               exit(1);\n> +               return -1;\n>         if (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))\n> -               exit(1);\n> +               return -1;\n> +       return 0;\n>  }\n>\n> diff --git a/apply.h b/apply.h\n> index 0f77f4d..f3b2ae4 100644\n> --- a/apply.h\n> +++ b/apply.h\n> @@ -117,8 +117,8 @@ extern int parse_whitespace_option(struct apply_state *state,\n>  extern int parse_ignorewhitespace_option(struct apply_state *state,\n>                                          const char *option);\n>\n> -extern void init_apply_state(struct apply_state *state,\n> -                            const char *prefix,\n> -                            struct lock_file *lock_file);\n> +extern int init_apply_state(struct apply_state *state,\n> +                           const char *prefix,\n> +                           struct lock_file *lock_file);\n>\n>  #endif\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> index 805c707..b31f9eb 100644\n> --- a/builtin/apply.c\n> +++ b/builtin/apply.c\n> @@ -4724,7 +4724,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\n>                 OPT_END()\n>         };\n>\n> -       init_apply_state(&state, prefix, NULL);\n> +       if (init_apply_state(&state, prefix, NULL))\n> +               exit(1);\n>\n>         argc = parse_options(argc, argv, state.prefix, builtin_apply_options,\n>                         apply_usage, 0);\n> --\n> 2.8.2.490.g3dabe57\n"},{"id":"286643","messageId":"CAPig+cQAM8i2sFY9UUYfN23PRGgFacG7KiTD6mZwnm=PgKBL7A@mail.gmail.com","threadId":"42281","inReplyTo":"20160511131745.2914-64-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 63/94] builtin/apply: make apply_all_patches() return -1 on error","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T03:44:43Z","receivedAt":"2016-05-16T03:44:43Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> To finish libifying the apply functionality, apply_all_patches() should not\n> die() or exit() in case of error, but return -1.\n>\n> While doing that we must take care that file descriptors are properly closed\n> and, if needed, reset a sensible value.\n>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n> diff --git a/builtin/apply.c b/builtin/apply.c\n> @@ -4613,9 +4613,10 @@ static int apply_all_patches(struct apply_state *state,\n>         }\n>\n>         if (state->update_index) {\n> -               if (write_locked_index(&the_index, state->lock_file, COMMIT_LOCK))\n> -                       die(_(\"Unable to write new index file\"));\n> +               res = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);\n>                 state->newfd = -1;\n\nDoes write_locked_index() unconditionally close the file descriptor\neven when an error occurs? If not, then isn't this potentially leaking\n'newfd'?\n\n(My very cursory read of write_locked_index() seems to reveal that the\nfile descriptor may indeed remain open upon index write failure.)\n\n> +               if (res)\n> +                       return error(_(\"Unable to write new index file\"));\n>         }\n>\n>         return !!errs;\n"},{"id":"286670","messageId":"xmqqwpmu2do5.fsf@gitster.mtv.corp.google.com","threadId":"42281","inReplyTo":"CAPig+cS98guXbeRH6oW8n2tPAa3u=2MvSx1H5rixGKdGTrVJPg@mail.gmail.com","subject":"Re: [PATCH v2 56/94] apply: move 'struct apply_state' to apply.h","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-16T16:03:22Z","receivedAt":"2016-05-16T16:03:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>> To libify `git apply` functionality we must make 'struct apply_state'\n>> usable outside \"builtin/apply.c\".\n>\n> Why is this patch plopped right in the middle of a bunch of other\n> patches which are making functions return -1 rather than die()ing?\n> Seems out of place.\n\nTwo possible places that would make more sense are (1) when it is\nintroduced very early in the series, or (2) when it absorbed all the\nfile-scope-static global states in the middle of the series.  I think\neither is fine.\n\nThat would be a good place to end the first batch of the topic.\nThen the second batch would be \"turn die() into error status that is\npropagated upwards\".\n"},{"id":"286679","messageId":"CAP8UFD0ewKeicNm=4frtdAz4YWR6-UuiBRXom0Ar-BKVpS36nA@mail.gmail.com","threadId":"42281","inReplyTo":"CAPig+cQrLZiwZm34+hFZXPmFGVtyPCvCEv4TwsTeL__cfzuORA@mail.gmail.com","subject":"Re: [PATCH v2 52/94] builtin/apply: read_patch_file() return -1 instead of die()ing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-16T17:19:25Z","receivedAt":"2016-05-16T17:19:25Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, May 16, 2016 at 3:56 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>> To libify `git apply` functionality we have to signal errors to the\n>> caller instead of die()ing. Let's do that by using error() instead\n>> of die()ing in read_patch_file().\n>>\n>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>> ---\n>> diff --git a/builtin/apply.c b/builtin/apply.c\n>> @@ -445,10 +445,10 @@ static void say_patch_name(FILE *output, const char *fmt, struct patch *patch)\n>> -static void read_patch_file(struct strbuf *sb, int fd)\n>> +static int read_patch_file(struct strbuf *sb, int fd)\n>>  {\n>>         if (strbuf_read(sb, fd, 0) < 0)\n>> -               die_errno(\"git apply: failed to read\");\n>> +               return error(\"git apply: failed to read: %s\", strerror(errno));\n>\n> When Duy's nd/error-errno series, which is in 'next', gets promoted to\n> 'master', then this could become:\n>\n>     return error_errno(...);\n\nYeah, sure.\n"},{"id":"286696","messageId":"CAP8UFD1Qwyi6uO4YTNB_RqR9QiCkuc9DbRb2JHTsiv9KrEjpeQ@mail.gmail.com","threadId":"42281","inReplyTo":"CAPig+cQkKijp_Mg0Ho0wAFSxmLin0EPA_a5PwV9DaHkHLJKNMA@mail.gmail.com","subject":"Re: [PATCH v2 54/94] builtin/apply: make parse_chunk() return a negative integer on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-16T18:19:11Z","receivedAt":"2016-05-16T18:19:11Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, May 16, 2016 at 5:04 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>> To libify `git apply` functionality we have to signal errors to the\n>> caller instead of die()ing or exit()ing.\n>>\n>> To do that in a compatible manner with the rest of the error handling\n>> in builtin/apply.c, find_header() should return -1 instead of calling\n>> die() or exit().\n>\n> Why is this talking about making find_header() return -1? Didn't that\n> happen in the previous patch?\n>\n>> As parse_chunk() is called only by apply_patch() which already\n>> returns -1 when an error happened, let's make apply_patch() return -1\n>> when parse_chunk() returns -1.\n>>\n>> If find_header() returns -2 because no patch header has been found, it\n>> is ok for parse_chunk() to also return -2. If find_header() returns -1\n>> because an error happened, it is ok for parse_chunk() to do the same.\n>>\n>> Helped-by: Eric Sunshine <sunshine@sunshineco.com>\n>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>> ---\n>> diff --git a/builtin/apply.c b/builtin/apply.c\n>> @@ -2176,8 +2176,9 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si\n>>                  * empty to us here.\n>>                  */\n>>                 if ((state->apply || state->check) &&\n>> -                   (!patch->is_binary && !metadata_changes(patch)))\n>> -                       die(_(\"patch with only garbage at line %d\"), state->linenr);\n>> +                   (!patch->is_binary && !metadata_changes(patch))) {\n>> +                       return error(_(\"patch with only garbage at line %d\"), state->linenr);\n>> +               }\n>\n> Unnecessary braces.\n\nOk, will remove.\n"},{"id":"287398","messageId":"CAP8UFD33fnHWgjKds5s65kpS_KjEH35yGqCG4Hvww7_cOE4drA@mail.gmail.com","threadId":"42281","inReplyTo":"CAP8UFD2i9rDi4K=2_hKmEwjtCgnkP6Bi6gFMymPgu2t-qsdA6g@mail.gmail.com","subject":"Re: [PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-24T08:15:48Z","receivedAt":"2016-05-24T08:15:48Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Fri, May 13, 2016 at 9:42 PM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> On Thu, May 12, 2016 at 9:56 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Christian Couder <christian.couder@gmail.com> writes:\n>>\n>>> This is just a small cleanup.\n>>\n>> ... which may have been better happened at 09/94.\n>\n> Ok, I will squash it in 09/94.\n\nThis has been done in the v3 I just sent, though I forgot to mention\nit in the changes.\n"},{"id":"287399","messageId":"CAP8UFD0FrK2tL49SLUxX5Zq4PHsmOP3aih9M9VAxw31P9eRH2Q@mail.gmail.com","threadId":"42281","inReplyTo":"xmqqy47c7awg.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 48/94] builtin/apply: rename 'prefix_' parameter to 'prefix'","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-24T08:24:30Z","receivedAt":"2016-05-24T08:24:30Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sat, May 14, 2016 at 8:27 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> On Thu, May 12, 2016 at 10:43 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Junio C Hamano <gitster@pobox.com> writes:\n>>>\n>>>> Up to this point, the conversion looks quite sensible, even though I\n>>>> think the organization of fields in apply_state do not look logical.\n>>>\n>>> I'd stop here for now, as everything before this step looks\n>>> uncontroversial.  Anybody whose tasked to move the global state for\n>>> these variables into a structure would reach the samestate after\n>>> applying these 48 patches, modulo minor differences in the way the\n>>> comments would say things, how the patches are split and how the\n>>> fields in apply_state() are organized.\n>>>\n>>> One thing that is missing is a counterpart of init_apply_state().\n>>> In the early part of patches where it added only \"const char *\"\n>>> borrowed from the caller and fields of intregral type, the lack of\n>>> clear_apply_state() did not mattter, but with a few fields with\n>>> \"string_list\" type, anybody who want to make repeated call into the\n>>> apply machinery would want a way to release the resource the\n>>> structure holds.\n>>>\n>>> Because 49/94 is a step to add an unfreeable resource, this is a\n>>> good place to stop and then add the clean_apply_state() before that\n>>> happens, I would think.  After that, I think both the contributor\n>>> and the reviewers would benefit if these early patches are merged\n>>> early without waiting for the review of the remainder.\n>>\n>> Ok, I will add add the clean_apply_state() and resend the patches up\n>> to that point soon, so that they can be merged early.\n>\n> Two more comments:\n>\n>  - Just like the change between v1 and v2, if we were to introduce\n>    clear_apply_state(), it would be nicer if it were done early in\n>    the series, ideally at the same time as init_apply_state() gets\n>    introduced,\n\nYeah, I have done that in v3.\n\n> or at least no later than the first field that holds\n>    resource that needs releasing is added.\n>\n>  - I didn't double check if 50 and later still had changes that\n>    belong to this \"early batch that moves things into a struct\" (aka\n>    cc/apply-introduce-state) topic, as I stopped at 49 and saw the\n>    need for clear_apply_state().  So 48 may not be the ideal place\n>    to stop.  From a cursory read of their titles, perhaps 49, 50, 56\n>    and possibly 60 should be in this early series?  While 60 does\n>    sound like an immediate follow-up to 09/94, it depends on a few\n>    \"die elimination\" changes, so I do NOT think it must be in the\n>    early batch.\n\nFor v3 I stopped at patch 50 from v2.\n\nPatch 56 moves 'struct apply_state' into apply.h and it can logically\nbelong to another patch series, as anyway 'struct apply_state' is not\nusable by other code as long as the related functions\n(init_apply_state(), clear_apply_state(), check_apply_state(), ...)\nare not also moved to apply.{c,h}.\n"},{"id":"288723","messageId":"CAP8UFD0Fow4HEp65D3Vbf=J4OtdeqxHZFDnnUABuyYkDJ3iXyg@mail.gmail.com","threadId":"42281","inReplyTo":"CAPig+cQkKijp_Mg0Ho0wAFSxmLin0EPA_a5PwV9DaHkHLJKNMA@mail.gmail.com","subject":"Re: [PATCH v2 54/94] builtin/apply: make parse_chunk() return a negative integer on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-06-08T15:14:11Z","receivedAt":"2016-06-08T15:14:11Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, May 16, 2016 at 5:04 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>> To libify `git apply` functionality we have to signal errors to the\n>> caller instead of die()ing or exit()ing.\n>>\n>> To do that in a compatible manner with the rest of the error handling\n>> in builtin/apply.c, find_header() should return -1 instead of calling\n>> die() or exit().\n>\n> Why is this talking about making find_header() return -1? Didn't that\n> happen in the previous patch?\n\nYeah, it should be parse_chunk() not find_header().\n\nThis is fixed in my current branch.\n\nThanks,\nChristian.\n"},{"id":"288725","messageId":"CAP8UFD0EwZMs0XotZE3jP1edUOUY87xRSZNPoKPS_sXJc7zE8A@mail.gmail.com","threadId":"42281","inReplyTo":"xmqqwpmu2do5.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 56/94] apply: move 'struct apply_state' to apply.h","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-06-08T15:25:10Z","receivedAt":"2016-06-08T15:25:10Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, May 16, 2016 at 6:03 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Eric Sunshine <sunshine@sunshineco.com> writes:\n>\n>> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n>> <christian.couder@gmail.com> wrote:\n>>> To libify `git apply` functionality we must make 'struct apply_state'\n>>> usable outside \"builtin/apply.c\".\n>>\n>> Why is this patch plopped right in the middle of a bunch of other\n>> patches which are making functions return -1 rather than die()ing?\n>> Seems out of place.\n>\n> Two possible places that would make more sense are (1) when it is\n> introduced very early in the series, or (2) when it absorbed all the\n> file-scope-static global states in the middle of the series.  I think\n> either is fine.\n>\n> That would be a good place to end the first batch of the topic.\n> Then the second batch would be \"turn die() into error status that is\n> propagated upwards\".\n\nI moved this patch at the beginning of second batch that I will send\nhopefully soon...\n"},{"id":"288731","messageId":"CAP8UFD2jA7ydsYTkQLbQJTW7NFRpkmJwgJQp=UZ0-8-7njSawA@mail.gmail.com","threadId":"42281","inReplyTo":"CAPig+cQAM8i2sFY9UUYfN23PRGgFacG7KiTD6mZwnm=PgKBL7A@mail.gmail.com","subject":"Re: [PATCH v2 63/94] builtin/apply: make apply_all_patches() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-06-08T16:37:38Z","receivedAt":"2016-06-08T16:37:38Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, May 16, 2016 at 5:44 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>> To finish libifying the apply functionality, apply_all_patches() should not\n>> die() or exit() in case of error, but return -1.\n>>\n>> While doing that we must take care that file descriptors are properly closed\n>> and, if needed, reset a sensible value.\n>>\n>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>> ---\n>> diff --git a/builtin/apply.c b/builtin/apply.c\n>> @@ -4613,9 +4613,10 @@ static int apply_all_patches(struct apply_state *state,\n>>         }\n>>\n>>         if (state->update_index) {\n>> -               if (write_locked_index(&the_index, state->lock_file, COMMIT_LOCK))\n>> -                       die(_(\"Unable to write new index file\"));\n>> +               res = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);\n>>                 state->newfd = -1;\n>\n> Does write_locked_index() unconditionally close the file descriptor\n> even when an error occurs? If not, then isn't this potentially leaking\n> 'newfd'?\n>\n> (My very cursory read of write_locked_index() seems to reveal that the\n> file descriptor may indeed remain open upon index write failure.)\n\nYou are right, it is leaking newfd if write_locked_index() fails.\nThe solution to that is to call `rollback_lock_file(state->lock_file)`\nand the following patch was supposed to do that:\n\n[PATCH v2 82/94] apply: roll back index lock file in case of error\n\nbut it would do that only if `state->newfd >= 0` so we should set\nstate->newfd to -1 only if write_locked_index() succeeds.\n\nI will fix this.\n\nI am also going to add a comment to this patch saying that this patch\nneeds a following patch to call rollback_lock_file(state->lock_file)\nin case of errors.\n\nOr if you prefer, I can squash the patch that call\nrollback_lock_file(state->lock_file) in case of errors into this\npatch.\n\nThanks,\nChristian.\n"},{"id":"288739","messageId":"CAPig+cQpk4Kknbudu1Ki3T9=rsO9+q4BCR6C2-1xjgUE0HSJYg@mail.gmail.com","threadId":"42281","inReplyTo":"CAP8UFD2jA7ydsYTkQLbQJTW7NFRpkmJwgJQp=UZ0-8-7njSawA@mail.gmail.com","subject":"Re: [PATCH v2 63/94] builtin/apply: make apply_all_patches() return -1 on error","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-06-08T17:44:22Z","receivedAt":"2016-06-08T17:44:22Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Jun 8, 2016 at 12:37 PM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> On Mon, May 16, 2016 at 5:44 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n>> <christian.couder@gmail.com> wrote:\n>>>         if (state->update_index) {\n>>> -               if (write_locked_index(&the_index, state->lock_file, COMMIT_LOCK))\n>>> -                       die(_(\"Unable to write new index file\"));\n>>> +               res = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);\n>>>                 state->newfd = -1;\n>>\n>> Does write_locked_index() unconditionally close the file descriptor\n>> even when an error occurs? If not, then isn't this potentially leaking\n>> 'newfd'?\n>>\n>> (My very cursory read of write_locked_index() seems to reveal that the\n>> file descriptor may indeed remain open upon index write failure.)\n>\n> You are right, it is leaking newfd if write_locked_index() fails.\n> The solution to that is to call `rollback_lock_file(state->lock_file)`\n> and the following patch was supposed to do that:\n>\n> [PATCH v2 82/94] apply: roll back index lock file in case of error\n>\n> but it would do that only if `state->newfd >= 0` so we should set\n> state->newfd to -1 only if write_locked_index() succeeds.\n>\n> I will fix this.\n>\n> I am also going to add a comment to this patch saying that this patch\n> needs a following patch to call rollback_lock_file(state->lock_file)\n> in case of errors.\n>\n> Or if you prefer, I can squash the patch that call\n> rollback_lock_file(state->lock_file) in case of errors into this\n> patch.\n\nSquashing may indeed be preferable over leaving it in a \"broken\" state\nuntil the next patch, though I haven't thought too hard about it.\nAlternately, can the two patches somehow be swapped?\n"},{"id":"288846","messageId":"5759DB31.2000106@kdbg.org","threadId":"42281","inReplyTo":"CAP8UFD1ukOMi_VDKzZErwSu1OBU5h1hVOxd7mPu1ytzFr11VGA@mail.gmail.com","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2016-06-09T21:10:09Z","receivedAt":"2016-06-16T02:19:50Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 12.05.2016 um 20:02 schrieb Christian Couder:\n> On Thu, May 12, 2016 at 7:06 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n>> Am 11.05.2016 um 15:16 schrieb Christian Couder:\n>>>\n>>> This is a patch series about libifying `git apply` functionality, and\n>>> using this libified functionality in `git am`, so that no 'git apply'\n>>> process is spawn anymore. This makes `git am` significantly faster, so\n>>> `git rebase`, when it uses the am backend, is also significantly\n>>> faster.\n>>\n>>\n>> I'm including this in my build on Windows. It passes the test suite.\n>\n> Great! Thanks for the report!\n>\n>> I'll also use it in production for a while, although I am not a git-am\n>> consumer nor do I use git-rebase without -i, hence, my tests will probably\n>> only show that there is no bad fall-out.\n\nMeanwhile, I have retrained my muscle memory to stop before typing \"-i\" \nafter \"rebase\" for an opportunity to consider whether bare rebase can be \nused.\n\nWhat should I say? I am impressed. It's like 100 times faster than \nrebase -i (on Windows). I'm now using it whenever I can, and more often \nthan not I plan my rebase workflow so that I can go ahead without -i.\n\nCan't wait to test a re-roll on top of cc/apply-introduce-state!\n\n-- Hannes\n"},{"id":"288856","messageId":"CAP8UFD0chzr9O9hpjQ00YruwfLof3gHj32292e3s=1SFmKdPzg@mail.gmail.com","threadId":"42281","inReplyTo":"CAPig+cQpk4Kknbudu1Ki3T9=rsO9+q4BCR6C2-1xjgUE0HSJYg@mail.gmail.com","subject":"Re: [PATCH v2 63/94] builtin/apply: make apply_all_patches() return -1 on error","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-06-09T22:01:06Z","receivedAt":"2016-06-16T02:19:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, Jun 8, 2016 at 7:44 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, Jun 8, 2016 at 12:37 PM, Christian Couder\n> <christian.couder@gmail.com> wrote:\n>> On Mon, May 16, 2016 at 5:44 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>> On Wed, May 11, 2016 at 9:17 AM, Christian Couder\n>>> <christian.couder@gmail.com> wrote:\n>>>>         if (state->update_index) {\n>>>> -               if (write_locked_index(&the_index, state->lock_file, COMMIT_LOCK))\n>>>> -                       die(_(\"Unable to write new index file\"));\n>>>> +               res = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);\n>>>>                 state->newfd = -1;\n>>>\n>>> Does write_locked_index() unconditionally close the file descriptor\n>>> even when an error occurs? If not, then isn't this potentially leaking\n>>> 'newfd'?\n>>>\n>>> (My very cursory read of write_locked_index() seems to reveal that the\n>>> file descriptor may indeed remain open upon index write failure.)\n>>\n>> You are right, it is leaking newfd if write_locked_index() fails.\n>> The solution to that is to call `rollback_lock_file(state->lock_file)`\n>> and the following patch was supposed to do that:\n>>\n>> [PATCH v2 82/94] apply: roll back index lock file in case of error\n>>\n>> but it would do that only if `state->newfd >= 0` so we should set\n>> state->newfd to -1 only if write_locked_index() succeeds.\n>>\n>> I will fix this.\n>>\n>> I am also going to add a comment to this patch saying that this patch\n>> needs a following patch to call rollback_lock_file(state->lock_file)\n>> in case of errors.\n>>\n>> Or if you prefer, I can squash the patch that call\n>> rollback_lock_file(state->lock_file) in case of errors into this\n>> patch.\n>\n> Squashing may indeed be preferable over leaving it in a \"broken\" state\n> until the next patch, though I haven't thought too hard about it.\n> Alternately, can the two patches somehow be swapped?\n\nI just squashed them for now as the result looks reasonable.\n"},{"id":"288866","messageId":"CAP8UFD2jCTgBhKGbf9pffX-EAoY3ovBxw2DRHZ6QtUkwEBr2=g@mail.gmail.com","threadId":"42281","inReplyTo":"5759DB31.2000106@kdbg.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-06-10T06:40:05Z","receivedAt":"2016-06-16T02:19:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, Jun 9, 2016 at 11:10 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 12.05.2016 um 20:02 schrieb Christian Couder:\n>>\n>>> I'll also use it in production for a while, although I am not a git-am\n>>> consumer nor do I use git-rebase without -i, hence, my tests will\n>>> probably\n>>> only show that there is no bad fall-out.\n>\n>\n> Meanwhile, I have retrained my muscle memory to stop before typing \"-i\"\n> after \"rebase\" for an opportunity to consider whether bare rebase can be\n> used.\n>\n> What should I say? I am impressed. It's like 100 times faster than rebase -i\n> (on Windows). I'm now using it whenever I can, and more often than not I\n> plan my rebase workflow so that I can go ahead without -i.\n\n:-D\n\nThanks for the report again!\n\n> Can't wait to test a re-roll on top of cc/apply-introduce-state!\n\nIt should happen really soon now...\n"},{"id":"288867","messageId":"alpine.DEB.2.20.1606100852550.3039@virtualbox","threadId":"42281","inReplyTo":"5759DB31.2000106@kdbg.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-06-10T07:01:42Z","receivedAt":"2016-06-16T02:19:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 9 Jun 2016, Johannes Sixt wrote:\n\n> Meanwhile, I have retrained my muscle memory to stop before typing \"-i\" after\n> \"rebase\" for an opportunity to consider whether bare rebase can be used.\n> \n> What should I say? I am impressed. It's like 100 times faster than rebase -i\n> (on Windows). I'm now using it whenever I can, and more often than not I plan\n> my rebase workflow so that I can go ahead without -i.\n\nThat only means that I have to finalize my rebase--helper work (which I am\nbusy doing, I am at the valgrind stage).\n\nI wonder whether that \"100x\" is a reliable number? ;-) FWIW I can measure\nsomething like a 4x speedup of the interactive rebase on Windows when\nrunning with the rebase--helper, and it is still noticably faster in my\nLinux VM, too.\n\n> Can't wait to test a re-roll on top of cc/apply-introduce-state!\n\nI lost track in the meantime: were those issues with unclosed file handles\nand unreleased memory in the error code paths addressed systematically? My\nmail about that seems to have been left unanswered, almost as if my\nconcerns had been hand-waved away...\n\nIf those issues have indeed been addressed properly, and a public\nrepository reliably has the newest iteration of that patch series in a\nbranch without a versioned name, I will be happy to test it in Git for\nWindows' SDK again.\n\nCiao,\nJohannes\n"},{"id":"288881","messageId":"CAP8UFD1zSAxyHfZgBbfoF=th0waZWEhvHP+4jUxxVO+rU9N9RA@mail.gmail.com","threadId":"42281","inReplyTo":"alpine.DEB.2.20.1606100852550.3039@virtualbox","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-06-10T08:59:46Z","receivedAt":"2016-06-16T02:19:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Hi Dscho,\n\nOn Fri, Jun 10, 2016 at 9:01 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Hannes,\n>\n> On Thu, 9 Jun 2016, Johannes Sixt wrote:\n>\n>> Meanwhile, I have retrained my muscle memory to stop before typing \"-i\" after\n>> \"rebase\" for an opportunity to consider whether bare rebase can be used.\n>>\n>> What should I say? I am impressed. It's like 100 times faster than rebase -i\n>> (on Windows). I'm now using it whenever I can, and more often than not I plan\n>> my rebase workflow so that I can go ahead without -i.\n>\n> That only means that I have to finalize my rebase--helper work (which I am\n> busy doing, I am at the valgrind stage).\n>\n> I wonder whether that \"100x\" is a reliable number? ;-) FWIW I can measure\n> something like a 4x speedup of the interactive rebase on Windows when\n> running with the rebase--helper, and it is still noticably faster in my\n> Linux VM, too.\n>\n>> Can't wait to test a re-roll on top of cc/apply-introduce-state!\n>\n> I lost track in the meantime: were those issues with unclosed file handles\n> and unreleased memory in the error code paths addressed systematically? My\n> mail about that seems to have been left unanswered, almost as if my\n> concerns had been hand-waved away...\n\nHaven't I answered to your email in this thread:\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/292403/\n\n?\n\n> If those issues have indeed been addressed properly, and a public\n> repository reliably has the newest iteration of that patch series in a\n> branch without a versioned name, I will be happy to test it in Git for\n> Windows' SDK again.\n\nThis is the newest iteration:\n\nhttps://github.com/chriscool/git/commits/libify-apply-use-in-am65\n\nThanks for testing,\nChristian.\n"},{"id":"288890","messageId":"alpine.DEB.2.20.1606101307080.3039@virtualbox","threadId":"42281","inReplyTo":"CAP8UFD1zSAxyHfZgBbfoF=th0waZWEhvHP+4jUxxVO+rU9N9RA@mail.gmail.com","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-06-10T11:11:35Z","receivedAt":"2016-06-16T02:19:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Christian,\n\nOn Fri, 10 Jun 2016, Christian Couder wrote:\n\n> On Fri, Jun 10, 2016 at 9:01 AM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Thu, 9 Jun 2016, Johannes Sixt wrote:\n> >\n> >> Meanwhile, I have retrained my muscle memory to stop before typing \"-i\" after\n> >> \"rebase\" for an opportunity to consider whether bare rebase can be used.\n> >>\n> >> What should I say? I am impressed. It's like 100 times faster than rebase -i\n> >> (on Windows). I'm now using it whenever I can, and more often than not I plan\n> >> my rebase workflow so that I can go ahead without -i.\n> >\n> > That only means that I have to finalize my rebase--helper work (which I am\n> > busy doing, I am at the valgrind stage).\n> >\n> > I wonder whether that \"100x\" is a reliable number? ;-) FWIW I can measure\n> > something like a 4x speedup of the interactive rebase on Windows when\n> > running with the rebase--helper, and it is still noticably faster in my\n> > Linux VM, too.\n> >\n> >> Can't wait to test a re-roll on top of cc/apply-introduce-state!\n> >\n> > I lost track in the meantime: were those issues with unclosed file handles\n> > and unreleased memory in the error code paths addressed systematically? My\n> > mail about that seems to have been left unanswered, almost as if my\n> > concerns had been hand-waved away...\n> \n> Haven't I answered to your email in this thread:\n> \n> http://thread.gmane.org/gmane.comp.version-control.git/292403/\n> \n> ?\n\nNot really. The reply (which I had not quite connected with my mail\nbecause they were over a week apart) says this:\n\n> I fixed this by moving the \"close(fd)\" call just after the\n> \"apply_patch()\" call.\n\nand this:\n\n> I will have another look at the 2 other places where there are\n> open()/close() or fopen()/fclose() calls.\n\nbut nothing about a careful, systematic investigation of all error code\npaths. As a consequence, I fully expect to encounter test failures as soon\nas I test your patch series again, simply because resources are still in\nuse when they should no longer be used. In other words, my expectations\nare now lower than they have been before, my concerns are not at all\naddressed.\n\n> > If those issues have indeed been addressed properly, and a public\n> > repository reliably has the newest iteration of that patch series in a\n> > branch without a versioned name, I will be happy to test it in Git for\n> > Windows' SDK again.\n> \n> This is the newest iteration:\n> \n> https://github.com/chriscool/git/commits/libify-apply-use-in-am65\n\nAnd that cute 65 in the name is the revision.\n\nCiao,\nJohannes\n"},{"id":"288934","messageId":"575AF304.8070407@kdbg.org","threadId":"42281","inReplyTo":"alpine.DEB.2.20.1606101307080.3039@virtualbox","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2016-06-10T17:04:04Z","receivedAt":"2016-06-16T02:19:51Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 10.06.2016 um 13:11 schrieb Johannes Schindelin:\n> On Fri, 10 Jun 2016, Christian Couder wrote:\n>> On Fri, Jun 10, 2016 at 9:01 AM, Johannes Schindelin\n>> <Johannes.Schindelin@gmx.de> wrote:\n>>> I lost track in the meantime: were those issues with unclosed file handles\n>>> and unreleased memory in the error code paths addressed systematically? My\n>>> mail about that seems to have been left unanswered, almost as if my\n>>> concerns had been hand-waved away...\n>>\n>> Haven't I answered to your email in this thread:\n>>\n>> http://thread.gmane.org/gmane.comp.version-control.git/292403/\n>>\n>> ?\n>\n> Not really. The reply (which I had not quite connected with my mail\n> because they were over a week apart) says this:\n>\n>> I fixed this by moving the \"close(fd)\" call just after the\n>> \"apply_patch()\" call.\n\nThis bug in v1 was discovered by the test suite and fixed in v2.\n\n>\n> and this:\n>\n>> I will have another look at the 2 other places where there are\n>> open()/close() or fopen()/fclose() calls.\n>\n> but nothing about a careful, systematic investigation of all error code\n> paths. As a consequence, I fully expect to encounter test failures as soon\n> as I test your patch series again, simply because resources are still in\n> use when they should no longer be used. In other words, my expectations\n> are now lower than they have been before, my concerns are not at all\n> addressed.\n\nDo you trust the test suite to some degree? It passes after the above \nbug was fixed in v2. In addition, haven't found any problems so far \nduring daily use.\n\n>> This is the newest iteration:\n>>\n>> https://github.com/chriscool/git/commits/libify-apply-use-in-am65\n>\n> And that cute 65 in the name is the revision.\n\nYeah, that number is painful. I would appreciate an unversioned branch \nname, too.\n\n-- Hannes\n"},{"id":"288990","messageId":"CAP8UFD1X6G4-C33PwZmV3LPb7e+-QQ60bcRbDA9gLaf9j6U+vw@mail.gmail.com","threadId":"42281","inReplyTo":"575AF304.8070407@kdbg.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-06-10T20:31:32Z","receivedAt":"2016-06-16T02:19:52Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Fri, Jun 10, 2016 at 7:04 PM, Johannes Sixt <j6t@kdbg.org> wrote:\n> Am 10.06.2016 um 13:11 schrieb Johannes Schindelin:\n>>\n>> Not really. The reply (which I had not quite connected with my mail\n>> because they were over a week apart) says this:\n>>\n>>> I fixed this by moving the \"close(fd)\" call just after the\n>>> \"apply_patch()\" call.\n>\n> This bug in v1 was discovered by the test suite and fixed in v2.\n>\n>> and this:\n>>\n>>> I will have another look at the 2 other places where there are\n>>> open()/close() or fopen()/fclose() calls.\n>>\n>> but nothing about a careful, systematic investigation of all error code\n>> paths. As a consequence, I fully expect to encounter test failures as soon\n>> as I test your patch series again, simply because resources are still in\n>> use when they should no longer be used. In other words, my expectations\n>> are now lower than they have been before, my concerns are not at all\n>> addressed.\n>\n> Do you trust the test suite to some degree? It passes after the above bug\n> was fixed in v2. In addition, haven't found any problems so far during daily\n> use.\n>\n>>> This is the newest iteration:\n>>>\n>>> https://github.com/chriscool/git/commits/libify-apply-use-in-am65\n>>\n>> And that cute 65 in the name is the revision.\n>\n> Yeah, that number is painful. I would appreciate an unversioned branch name,\n> too.\n\nOk, you can use\nhttps://github.com/chriscool/git/commits/libify-apply-use-in-am then.\n\nThanks,\nChristian.\n"},{"id":"289011","messageId":"alpine.DEB.2.20.1606110849340.3039@virtualbox","threadId":"42281","inReplyTo":"575AF304.8070407@kdbg.org","subject":"Re: [PATCH v2 00/94] libify apply and use lib in am","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-06-11T07:02:19Z","receivedAt":"2016-06-16T02:19:52Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Fri, 10 Jun 2016, Johannes Sixt wrote:\n\n> Am 10.06.2016 um 13:11 schrieb Johannes Schindelin:\n> > On Fri, 10 Jun 2016, Christian Couder wrote:\n> >\n> > > I fixed this by moving the \"close(fd)\" call just after the\n> > > \"apply_patch()\" call.\n> \n> This bug in v1 was discovered by the test suite and fixed in v2.\n\nMaybe it would be a good idea to fix test failures before sending out an\n80-strong patch series.\n\nJust sayin'.\n\n> > and this:\n> >\n> > > I will have another look at the 2 other places where there are\n> > > open()/close() or fopen()/fclose() calls.\n> >\n> > but nothing about a careful, systematic investigation of all error code\n> > paths. As a consequence, I fully expect to encounter test failures as soon\n> > as I test your patch series again, simply because resources are still in\n> > use when they should no longer be used. In other words, my expectations\n> > are now lower than they have been before, my concerns are not at all\n> > addressed.\n> \n> Do you trust the test suite to some degree?\n\nYes. To *some* degree.\n\nFor comparison, my rebase--helper patches pass the test suite for more\nthan a month now. I still discovered two minor problems and fixed them\nyesterday.\n\nOur test suite (and *any* test suite, really) is in *no way* a substitute\nfor proper review. And the first review needs to be performed by the\ndeveloper herself.\n\nJust compare the two options: to add tests for each and every corner case,\nespecially error code paths, or alternatively just going through the patch\nmanually, inspecting every error code path from the used-resource point of\nview?\n\nI am sure you agree that the latter is a much better use of everybody's\ntime, and also that that review will be most effective when performed by\nthe person most familiar with the patches.\n\n> It passes after the above bug was fixed in v2. In addition, haven't\n> found any problems so far during daily use.\n\nI put much more stock into the latter than the former. The former is\nrequired, to be sure, but by far not sufficient.\n\nTBH I was quite disappointed when I tried to run v1 and found such a\nsimple bug right away, which made me wonder how many more not-so-simple\nbugs were to be found. All that, while I really wanted this patch series\nto be good enough to enter core Git's code base.\n\n> > > This is the newest iteration:\n> > >\n> > > https://github.com/chriscool/git/commits/libify-apply-use-in-am65\n> >\n> > And that cute 65 in the name is the revision.\n> \n> Yeah, that number is painful. I would appreciate an unversioned branch\n> name, too.\n\nTo be frank, I think that a version number in a branch name is incorrect\nGit usage. Version numbers are something for tags, not for branches (I\nwould understand partial version numbers in maintenance branches, of\ncourse, because then they would not version the *branch* but convey the\npurpose of the branch, as names should).\n\nCiao,\nJohannes\n"}]}