{"thread":{"id":"25834","subject":"[PATCH v2] git apply: apply patches with -pN (N>1) properly for some cases.","startedAt":"2010-11-25T02:58:43Z","lastAt":"2010-11-25T02:58:43Z","messageCount":1,"participants":["Jiang Xin"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"156518","messageId":"4CEDD0E3.6050905@gmail.com","threadId":"25834","inReplyTo":null,"subject":"[PATCH v2] git apply: apply patches with -pN (N>1) properly for some cases.","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2010-11-25T02:58:43Z","receivedAt":"2010-11-25T02:58:43Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"In some cases when apply patch, there maybe no '--- path/to/old'\nand '+++ path/to/new' lines in the patch file, and the only way\nto get filename is from the 'diff --git path/to/old path/to/new'\nline in the patch header. For example, differ of binary files,\npure mode changes, removing or adding empty files.\n\nThe function 'git_header_name' is broken and casue patch apply\nfailed with -pN (N>1) for these cases. This patch fixed it and\nprovide a testcase. I also add a testcase for fancy filename.\n\nSigned-off-by: Jiang Xin <jiangxin@ossxp.com>\n---\n builtin/apply.c       |    3 ++-\n t/t4120-apply-popt.sh |   11 +++++++++++\n 2 files changed, 13 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 23c18c5..d603e37 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -1126,6 +1126,7 @@ static char *git_header_name(char *line, int llen)\n \t * form.\n \t */\n \tfor (len = 0 ; ; len++) {\n+\t\tint nslash = p_value;\n \t\tswitch (name[len]) {\n \t\tdefault:\n \t\t\tcontinue;\n@@ -1137,7 +1138,7 @@ static char *git_header_name(char *line, int llen)\n \t\t\t\tchar c = *second++;\n \t\t\t\tif (c == '\\n')\n \t\t\t\t\treturn NULL;\n-\t\t\t\tif (c == '/')\n+\t\t\t\tif (c == '/' && --nslash <= 0)\n \t\t\t\t\tbreak;\n \t\t\t}\n \t\t\tif (second[len] == '\\n' && !memcmp(name, second, len)) {\ndiff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh\nindex 2b2d00b..8a1e80e 100755\n--- a/t/t4120-apply-popt.sh\n+++ b/t/t4120-apply-popt.sh\n@@ -50,10 +50,21 @@ test_expect_success 'apply (-p2) traditional diff with funny filenames' '\n \ttest_cmp expected file1\n '\n \n+test_expect_success 'apply git diff with -p2 and fancy filename' '\n+\tcp file1.saved file1 &&\n+\tgit apply -p2 patch.escaped\n+'\n+\n test_expect_success 'apply with too large -p and fancy filename' '\n \tcp file1.saved file1 &&\n \ttest_must_fail git apply --stat -p3 patch.escaped 2>err &&\n \tgrep \"removing 3 leading\" err\n '\n \n+test_expect_success 'apply git diff with -p2 and use default name from header' '\n+\tsed -e \"/^\\(---\\|+++\\) / d\" patch.file > patch.newheader &&\n+\tcp file1.saved file1 &&\n+\tgit apply -p2 patch.newheader\n+'\n+\n test_done\n-- \n1.7.3.2.245.g03276.dirty\n"}]}