{"thread":{"id":"1682","subject":"[PATCH 7/9] New option --ignore-applied for git-apply.","startedAt":"2005-08-28T15:24:52Z","lastAt":"2005-08-28T21:06:48Z","messageCount":5,"participants":["Robert Fitzsimons","Linus Torvalds","A Large Angry SCM","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"7872","messageId":"1125242692932-git-send-email-robfitz@273k.net","threadId":"1682","inReplyTo":"11252426793534-git-send-email-robfitz@273k.net","subject":"[PATCH 6/9] New option --ignore-whitespace for git-apply.","fromName":"Robert Fitzsimons","fromEmail":"robfitz@273k.net","sentAt":"2005-08-28T15:24:52Z","receivedAt":"2005-08-28T15:24:52Z","isPatch":true,"sender":{"key":"robfitz@273k.net","avatar":null},"body":"Allow the user to force a patch to be applied even though there might\nbe whitespace differences.  Added a test case for the new option.\n\nSigned-off-by: Robert Fitzsimons <robfitz@273k.net>\n\n---\n\n Documentation/git-apply.txt        |    7 +++-\n apply.c                            |   38 ++++++++++++++++++-\n t/t4107-apply-ignore-whitespace.sh |   72 ++++++++++++++++++++++++++++++++++++\n 3 files changed, 113 insertions(+), 4 deletions(-)\n create mode 100644 t/t4107-apply-ignore-whitespace.sh\n\na928441d83ccc347b1d57fc561d413da56b93197\ndiff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt\n--- a/Documentation/git-apply.txt\n+++ b/Documentation/git-apply.txt\n@@ -11,7 +11,8 @@ SYNOPSIS\n --------\n 'git-apply' [--no-merge] [--stat] [--summary] [--check]\n \t\t[--index] [--show-files] [--apply]\n-\t\t[--force-delete] [<patch>...]\n+\t\t[--force-delete] [--ignore-whitespace]\n+\t\t[<patch>...]\n \n DESCRIPTION\n -----------\n@@ -68,6 +69,10 @@ OPTIONS\n \tfile contents would be left behind, lines added or the\n \tpatch will not apply.\n \n+--ignore-whitespace::\n+\tWhen matching the patch to the file contents ignore\n+\tsequences of tabs or spaces.\n+\n Author\n ------\n Written by Linus Torvalds <torvalds@osdl.org>\ndiff --git a/apply.c b/apply.c\n--- a/apply.c\n+++ b/apply.c\n@@ -33,8 +33,9 @@ static int check = 0;\n static int apply = 1;\n static int show_files = 0;\n static int force_delete = 0;\n+static int ignore_whitespace = 0;\n static const char apply_usage[] =\n-\"git-apply [--no-merge] [--stat] [--summary] [--check] [--index] [--apply] [--show-files] [--force-delete] <patch>...\";\n+\"git-apply [--no-merge] [--stat] [--summary] [--check] [--index] [--apply] [--show-files] [--force-delete] [--ignore-whitespace] <patch>...\";\n \n /*\n  * For \"diff-stat\" like behaviour, we keep track of the biggest change\n@@ -109,6 +110,27 @@ static void *read_patch_file(int fd, uns\n \treturn buffer;\n }\n \n+static int memcmp_ignore_whitespace(const char *s1, const char *s2, size_t n)\n+{\n+\tconst char *stop = s1 + n;\n+\tint result;\n+\n+\tif (!n)\n+\t\treturn 0;\n+\n+\tdo {\n+\t\tif (((*s1 == ' ') || (*s1 == '\\t')) && ((*s2 == ' ') || (*s2 == '\\t'))) {\n+\t\t\twhile ((*s1 == ' ') || (*s1 == '\\t'))\n+\t\t\t\ts1++;\n+\t\t\twhile ((*s2 == ' ') || (*s2 == '\\t'))\n+\t\t\t\ts2++;\n+\t\t}\n+\t\tresult = *s1++ - *s2++;\n+\t} while (!result && (s1 < stop));\n+\n+\treturn result;\n+}\n+\n static unsigned long linelen(const char *buffer, unsigned long size)\n {\n \tunsigned long len = 0;\n@@ -839,7 +861,10 @@ static int find_offset(const char *buf, \n \t}\n \n \t/* Exact line number? */\n-\tif (!memcmp(buf + start, fragment, fragsize))\n+\tif (ignore_whitespace) {\n+\t\tif (!memcmp_ignore_whitespace(buf + start, fragment, fragsize))\n+\t\t\treturn start;\n+\t} else if (!memcmp(buf + start, fragment, fragsize))\n \t\treturn start;\n \n \t/*\n@@ -873,7 +898,10 @@ static int find_offset(const char *buf, \n \n \t\tif (try + fragsize > size)\n \t\t\tcontinue;\n-\t\tif (memcmp(buf + try, fragment, fragsize))\n+\t\tif (ignore_whitespace) {\n+\t\t\tif (memcmp_ignore_whitespace(buf + try, fragment, fragsize))\n+\t\t\t\tcontinue;\n+\t\t} else if (memcmp(buf + try, fragment, fragsize))\n \t\t\tcontinue;\n \t\tn = (i >> 1)+1;\n \t\tif (i & 1)\n@@ -1575,6 +1603,10 @@ int main(int argc, char **argv)\n \t\t\tforce_delete = 1;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(arg, \"--ignore-whitespace\")) {\n+\t\t\tignore_whitespace = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tfd = open(arg, O_RDONLY);\n \t\tif (fd < 0)\n \t\t\tusage(apply_usage);\ndiff --git a/t/t4107-apply-ignore-whitespace.sh b/t/t4107-apply-ignore-whitespace.sh\nnew file mode 100644\n--- /dev/null\n+++ b/t/t4107-apply-ignore-whitespace.sh\n@@ -0,0 +1,72 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2005 Junio C Hamano\n+# Copyright (c) 2005 Robert Fitzsimons\n+#\n+\n+test_description='git-apply --ignore-whitespace.\n+\n+'\n+. ./test-lib.sh\n+\n+# setup\n+\n+cat > patch1.patch <<\\EOF\n+diff --git a/main.c b/main.c\n+new file mode 100644\n+--- /dev/null\n++++ b/main.c\n+@@ -0,0 +1,23 @@\n++#include <stdio.h>\n++\n++void print_int(int num);\n++int func(int num);\n++\n++int main() {\n++       int i;\n++\n++       for (i = 0; i < 10; i++) {\n++               print_int(func(i));\n++       }\n++\n++       return 0;\n++}\n++\n++int func(int num) {\n++       return num * num;\n++}\n++\n++void print_int(int num) {\n++       printf(\"%d\", num);\n++}\n++\n+EOF\n+cat > patch2.patch <<\\EOF\n+diff --git a/main.c b/main.c\n+--- a/main.c\n++++ b/main.c\n+@@ -10,6 +10,8 @@\n+ \t\tprint_int(func(i));\n+ \t}\n+ \n++\tprintf(\"\\n\");\n++\n+ \treturn 0;\n+ }\n+EOF\n+\n+test_expect_success \"S = patch1\" \\\n+    'git-apply patch1.patch'\n+\n+test_expect_failure \"F = patch2\" \\\n+    'git-apply patch2.patch'\n+\n+test_expect_success \"S = patch2 (--ignore-whitespace)\" \\\n+    'git-apply --ignore-whitespace patch2.patch'\n+\n+rm -f main.c\n+test_expect_success \"S = patch1 (--ignore-whitespace)\" \\\n+    'git-apply --ignore-whitespace patch1.patch'\n+\n+test_done\n+\n"},{"id":"7870","messageId":"11252426961236-git-send-email-robfitz@273k.net","threadId":"1682","inReplyTo":"1125242692932-git-send-email-robfitz@273k.net","subject":"[PATCH 7/9] New option --ignore-applied for git-apply.","fromName":"Robert Fitzsimons","fromEmail":"robfitz@273k.net","sentAt":"2005-08-28T15:24:56Z","receivedAt":"2005-08-28T15:24:56Z","isPatch":true,"sender":{"key":"robfitz@273k.net","avatar":null},"body":"Allow the user to allow a patch which has some hunks (fragments)\nalready applied to succeed.  Added test case and documentation.\n\nSigned-off-by: Robert Fitzsimons <robfitz@273k.net>\n\n---\n\n Documentation/git-apply.txt     |    6 ++\n apply.c                         |   12 +++++\n t/t4108-apply-ignore-applied.sh |   94 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 110 insertions(+), 2 deletions(-)\n create mode 100644 t/t4108-apply-ignore-applied.sh\n\n5e36f3b7c8ca0710096552ce3f20f16da04e601b\ndiff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt\n--- a/Documentation/git-apply.txt\n+++ b/Documentation/git-apply.txt\n@@ -12,7 +12,7 @@ SYNOPSIS\n 'git-apply' [--no-merge] [--stat] [--summary] [--check]\n \t\t[--index] [--show-files] [--apply]\n \t\t[--force-delete] [--ignore-whitespace]\n-\t\t[<patch>...]\n+\t\t[--ignore-applied] [<patch>...]\n \n DESCRIPTION\n -----------\n@@ -73,6 +73,10 @@ OPTIONS\n \tWhen matching the patch to the file contents ignore\n \tsequences of tabs or spaces.\n \n+--ignore-applied::\n+\tIf a patch hunk (fragment) fails to apply, reverse the\n+\thunk and check if the hunk has already been applied.\n+\n Author\n ------\n Written by Linus Torvalds <torvalds@osdl.org>\ndiff --git a/apply.c b/apply.c\n--- a/apply.c\n+++ b/apply.c\n@@ -34,8 +34,9 @@ static int apply = 1;\n static int show_files = 0;\n static int force_delete = 0;\n static int ignore_whitespace = 0;\n+static int ignore_applied = 0;\n static const char apply_usage[] =\n-\"git-apply [--no-merge] [--stat] [--summary] [--check] [--index] [--apply] [--show-files] [--force-delete] [--ignore-whitespace] <patch>...\";\n+\"git-apply [--no-merge] [--stat] [--summary] [--check] [--index] [--apply] [--show-files] [--force-delete] [--ignore-whitespace] [--ignore-applied] <patch>...\";\n \n /*\n  * For \"diff-stat\" like behaviour, we keep track of the biggest change\n@@ -985,6 +986,11 @@ static int apply_one_fragment(struct buf\n \t\tmemmove(buf + offset + newsize, buf + offset + oldsize, size - offset - newsize);\n \t\tmemcpy(buf + offset, new, newsize);\n \t\toffset = 0;\n+\t} else if (ignore_applied) {\n+\t\toffset = find_offset(buf, desc->size, new, newsize, frag->newpos);\n+\t\tif (offset >= 0) {\n+\t\t\toffset = 0;\n+\t\t}\n \t}\n \n \tfree(old);\n@@ -1607,6 +1613,10 @@ int main(int argc, char **argv)\n \t\t\tignore_whitespace = 1;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(arg, \"--ignore-applied\")) {\n+\t\t\tignore_applied = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tfd = open(arg, O_RDONLY);\n \t\tif (fd < 0)\n \t\t\tusage(apply_usage);\ndiff --git a/t/t4108-apply-ignore-applied.sh b/t/t4108-apply-ignore-applied.sh\nnew file mode 100644\n--- /dev/null\n+++ b/t/t4108-apply-ignore-applied.sh\n@@ -0,0 +1,94 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2005 Junio C Hamano\n+# Copyright (c) 2005 Robert Fitzsimons\n+#\n+\n+test_description='git-apply --ignore-applied.\n+\n+'\n+. ./test-lib.sh\n+\n+# setup\n+\n+cat > patch1.patch <<\\EOF\n+diff --git a/main.c b/main.c\n+new file mode 100644\n+--- /dev/null\n++++ b/main.c\n+@@ -0,0 +1,23 @@\n++#include <stdio.h>\n++\n++void print_int(int num);\n++int func(int num);\n++\n++int main() {\n++\tint i;\n++\n++\tfor (i = 0; i < 10; i++) {\n++\t\tprint_int(func(i));\n++\t}\n++\n++\treturn 0;\n++}\n++\n++int func(int num) {\n++\treturn num * num;\n++}\n++\n++void print_int(int num) {\n++\tprintf(\"%d\", num);\n++}\n++\n+EOF\n+cat > patch2.patch <<\\EOF\n+diff --git a/main.c b/main.c\n+--- a/main.c\n++++ b/main.c\n+@@ -10,6 +10,8 @@\n+ \t\tprint_int(func(i));\n+ \t}\n+ \n++\tprintf(\"\\n\");\n++\n+ \treturn 0;\n+ }\n+ \n+EOF\n+cat > patch3.patch <<\\EOF\n+diff --git a/main.c b/main.c\n+--- a/main.c\n++++ b/main.c\n+@@ -10,6 +10,8 @@\n+ \t\tprint_int(func(i));\n+ \t}\n+ \n++\tprintf(\"\\n\");\n++\n+ \treturn 0;\n+ }\n+ \n+@@ -18,6 +20,6 @@\n+ }\n+ \n+ void print_int(int num) {\n+-\tprintf(\"%d\", num);\n++\tprintf(\"%d \", num);\n+ }\n+ \n+EOF\n+\n+test_expect_failure \"F = test 1\" \\\n+    'cat patch1.patch patch2.patch patch2.patch | git-apply --check'\n+\n+test_expect_success \"S = test 2\" \\\n+    'cat patch1.patch patch2.patch patch2.patch | git-apply --check --ignore-applied'\n+\n+test_expect_failure \"F = test 3\" \\\n+    'cat patch1.patch patch3.patch patch3.patch | git-apply --check'\n+\n+test_expect_success \"S = test 4\" \\\n+    'cat patch1.patch patch2.patch patch3.patch | git-apply --check --ignore-applied'\n+\n+test_done\n+\n"},{"id":"7875","messageId":"Pine.LNX.4.58.0508280956320.3317@g5.osdl.org","threadId":"1682","inReplyTo":"1125242692932-git-send-email-robfitz@273k.net","subject":"Re: [PATCH 6/9] New option --ignore-whitespace for git-apply.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-08-28T16:58:15Z","receivedAt":"2005-08-28T16:58:15Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 28 Aug 2005, Robert Fitzsimons wrote:\n>\n> Allow the user to force a patch to be applied even though there might\n> be whitespace differences.  Added a test case for the new option.\n\nIf you ignore whitespace, then you should probably accept patches that are\nwhitespace corrupted in another way: lines missing the ' ' at the\nbeginning. Especially lines that are empty. That's actually the most \ncommon form of whitespace corruption there is.\n\n\t\tLinus\n"},{"id":"7880","messageId":"4312235F.2040907@gmail.com","threadId":"1682","inReplyTo":"Pine.LNX.4.58.0508280956320.3317@g5.osdl.org","subject":"Re: [PATCH 6/9] New option --ignore-whitespace for git-apply.","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2005-08-28T20:49:35Z","receivedAt":"2005-08-28T20:49:35Z","isPatch":true,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Linus Torvalds wrote:\n> On Sun, 28 Aug 2005, Robert Fitzsimons wrote:\n>>Allow the user to force a patch to be applied even though there might\n>>be whitespace differences.  Added a test case for the new option.\n> \n> If you ignore whitespace, then you should probably accept patches that are\n> whitespace corrupted in another way: lines missing the ' ' at the\n> beginning. Especially lines that are empty. That's actually the most \n> common form of whitespace corruption there is.\n\nActually, a more restricted from of --ignore-whitespace may be useful, \n--ignore-trailing-whitespace (needs a shorter name!). Ignore only \ntrailing whitespace differences (including empty context lines without \nthe initial space).\n"},{"id":"7884","messageId":"7vu0h9kbyv.fsf@assigned-by-dhcp.cox.net","threadId":"1682","inReplyTo":"1125242692932-git-send-email-robfitz@273k.net","subject":"Re: [PATCH 6/9] New option --ignore-whitespace for git-apply.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-28T21:06:48Z","receivedAt":"2005-08-28T21:06:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Robert Fitzsimons <robfitz@273k.net> writes:\n\n> Allow the user to force a patch to be applied even though there might\n> be whitespace differences.  Added a test case for the new option.\n\nIt might be worth doing fuzz in general, but treating\nwhitespace-only fuzz specially is a good idea, since they are\nusually more benign.\n"}]}