{"thread":{"id":"55175","subject":"[PATCH 1/2] add: add option --no-filters to disable attribute-based filtering","startedAt":"2021-02-19T18:12:59Z","lastAt":"2021-02-20T21:35:36Z","messageCount":11,"participants":["Andrej Shadura via GitGitGadget","brian m. carlson","Andrej Shadura","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"417415","messageId":"pull.880.git.1613758333.gitgitgadget@gmail.com","threadId":"55175","inReplyTo":null,"subject":"[PATCH 0/2] Add --no-filters option to git-add","fromName":"Andrej Shadura via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-19T18:12:11Z","receivedAt":"2021-02-19T18:12:59Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"It is possible for a user to disable attribute-based filtering when\ncommitting by doing one of the following:\n\n * Create .git/info/attributes unapplying all possible transforming\n   attributes.\n * Use git hash-object and git update-index to stage files manually.\n\nDoing the former requires keeping an up-to-date list of all attributes which\ncan transform files when committing or checking out. Doing the latter is\ndifficult, error-prone and slow when done from scripts.\n\nInstead, similarly to git hash-object, --no-filter can be added to git add\nto enable temporarily disabling filtering in an easy to use way.\n\nThese patches:\n\n * Add new flag ADD_CACHE_RAW to add_to_index()\n * Add new flag HASH_RAW to index_fd()\n * Make git hash-object use the new HASH_RAW flag for consistency\n * Add tests for the new git-add option.\n\nAndrej Shadura (2):\n  add: add option --no-filters to disable attribute-based filtering\n  hash-object: use the new HASH_RAW flag instead of setting path to NULL\n\n Documentation/git-add.txt |  7 +++++-\n builtin/add.c             |  3 +++\n builtin/hash-object.c     | 17 ++++++---------\n cache.h                   |  2 ++\n object-file.c             |  2 +-\n read-cache.c              |  3 +++\n t/t2205-add-no-filters.sh | 46 +++++++++++++++++++++++++++++++++++++++\n 7 files changed, 68 insertions(+), 12 deletions(-)\n create mode 100755 t/t2205-add-no-filters.sh\n\n\nbase-commit: 2283e0e9af55689215afa39c03beb2315ce18e83\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-880%2Fandrewshadura%2Fgit-add-no-filters-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-880/andrewshadura/git-add-no-filters-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/880\n-- \ngitgitgadget\n"},{"id":"417413","messageId":"cf8eb886a1e29c94ee5ec070fb380d6bc36f40db.1613758333.git.gitgitgadget@gmail.com","threadId":"55175","inReplyTo":"pull.880.git.1613758333.gitgitgadget@gmail.com","subject":"[PATCH 1/2] add: add option --no-filters to disable attribute-based filtering","fromName":"Andrej Shadura via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-19T18:12:12Z","receivedAt":"2021-02-19T18:13:00Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"From: Andrej Shadura <andrew.shadura@collabora.co.uk>\n\nIt is possible for a user to disable attribute-based filtering when\ncommitting by doing one of the following:\n\n* Create .git/info/attributes unapplying all possible transforming\n  attributes.\n* Use git hash-object and git update-index to stage files manually.\n\nDoing the former requires keeping an up-to-date list of all attributes\nwhich can transform files when committing or checking out.\nDoing the latter is difficult, error-prone and slow when done from\nscripts.\n\nInstead, similarly to git hash-object, --no-filter can be added to\ngit add to enable temporarily disabling filtering in an easy to use\nway:\n\n* Add new flag ADD_CACHE_RAW to add_to_index()\n* Add new flag HASH_RAW to index_fd()\n\nSigned-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>\n---\n Documentation/git-add.txt |  7 +++++-\n builtin/add.c             |  3 +++\n cache.h                   |  2 ++\n object-file.c             |  2 +-\n read-cache.c              |  3 +++\n t/t2205-add-no-filters.sh | 46 +++++++++++++++++++++++++++++++++++++++\n 6 files changed, 61 insertions(+), 2 deletions(-)\n create mode 100755 t/t2205-add-no-filters.sh\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex be5e3ac54b85..b3d7b13e83f4 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]\n-\t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n+\t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--no-filters]\n \t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize]\n \t  [--chmod=(+|-)x] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n \t  [--] [<pathspec>...]\n@@ -183,6 +183,11 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n \tin order to correct files added with wrong CRLF/LF line endings.\n \tThis option implies `-u`.\n \n+--no-filters::\n+\tAdd the contents as is, ignoring any input filter that would\n+\thave been chosen by the attributes mechanism, including the end-of-line\n+\tconversion.\n+\n --chmod=(+|-)x::\n \tOverride the executable bit of the added files.  The executable\n \tbit is only changed in the index, the files on disk are left\ndiff --git a/builtin/add.c b/builtin/add.c\nindex a825887c503d..609a0e6c0157 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -29,6 +29,7 @@ static const char * const builtin_add_usage[] = {\n static int patch_interactive, add_interactive, edit_interactive;\n static int take_worktree_changes;\n static int add_renormalize;\n+static int no_filters;\n static int pathspec_file_nul;\n static const char *pathspec_from_file;\n static int legacy_stash_p; /* support for the scripted `git stash` */\n@@ -334,6 +335,7 @@ static struct option builtin_add_options[] = {\n \tOPT__FORCE(&ignored_too, N_(\"allow adding otherwise ignored files\"), 0),\n \tOPT_BOOL('u', \"update\", &take_worktree_changes, N_(\"update tracked files\")),\n \tOPT_BOOL(0, \"renormalize\", &add_renormalize, N_(\"renormalize EOL of tracked files (implies -u)\")),\n+\tOPT_BOOL(0 , \"no-filters\", &no_filters, N_(\"store file as is without filters\")),\n \tOPT_BOOL('N', \"intent-to-add\", &intent_to_add, N_(\"record only the fact that the path will be added later\")),\n \tOPT_BOOL('A', \"all\", &addremove_explicit, N_(\"add changes from all tracked and untracked files\")),\n \tOPT_CALLBACK_F(0, \"ignore-removal\", &addremove_explicit,\n@@ -531,6 +533,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t (show_only ? ADD_CACHE_PRETEND : 0) |\n \t\t (intent_to_add ? ADD_CACHE_INTENT : 0) |\n \t\t (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |\n+\t\t (no_filters ? ADD_CACHE_RAW : 0) |\n \t\t (!(addremove || take_worktree_changes)\n \t\t  ? ADD_CACHE_IGNORE_REMOVAL : 0));\n \ndiff --git a/cache.h b/cache.h\nindex d92814961405..df83b5709c32 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -820,6 +820,7 @@ int remove_file_from_index(struct index_state *, const char *path);\n #define ADD_CACHE_IGNORE_ERRORS\t4\n #define ADD_CACHE_IGNORE_REMOVAL 8\n #define ADD_CACHE_INTENT 16\n+#define ADD_CACHE_RAW 32\n /*\n  * These two are used to add the contents of the file at path\n  * to the index, marking the working tree up-to-date by storing\n@@ -858,6 +859,7 @@ int ie_modified(struct index_state *, const struct cache_entry *, struct stat *,\n #define HASH_WRITE_OBJECT 1\n #define HASH_FORMAT_CHECK 2\n #define HASH_RENORMALIZE  4\n+#define HASH_RAW          8\n int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);\n int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags);\n \ndiff --git a/object-file.c b/object-file.c\nindex 5bcfde847188..74487c22e586 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2067,7 +2067,7 @@ static int index_mem(struct index_state *istate,\n \t/*\n \t * Convert blobs to git internal format\n \t */\n-\tif ((type == OBJ_BLOB) && path) {\n+\tif ((type == OBJ_BLOB) && path && !(flags & HASH_RAW)) {\n \t\tstruct strbuf nbuf = STRBUF_INIT;\n \t\tif (convert_to_git(istate, path, buf, size, &nbuf,\n \t\t\t\t   get_conv_flags(flags))) {\ndiff --git a/read-cache.c b/read-cache.c\nindex 29144cf879e7..0fb31201c705 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -716,6 +716,9 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \tif (flags & ADD_CACHE_RENORMALIZE)\n \t\thash_flags |= HASH_RENORMALIZE;\n \n+\tif (flags & ADD_CACHE_RAW)\n+\t\thash_flags |= HASH_RAW;\n+\n \tif (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))\n \t\treturn error(_(\"%s: can only add regular files, symbolic links or git-directories\"), path);\n \ndiff --git a/t/t2205-add-no-filters.sh b/t/t2205-add-no-filters.sh\nnew file mode 100755\nindex 000000000000..a897ed810827\n--- /dev/null\n+++ b/t/t2205-add-no-filters.sh\n@@ -0,0 +1,46 @@\n+#!/bin/sh\n+\n+test_description='git add --no-filters\n+\n+This test creates a file and a corresponding .gitattributes setup\n+to ensure the file undergoes a conversion when committed or checked\n+out.\n+\n+It then verifies that the conversion happens by default, but does not\n+when --no-filters is used.'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo \"* eol=crlf\" > .gitattributes &&\n+\tgit add .gitattributes &&\n+\tgit commit -m initial &&\n+\tprintf \"test\\r\\ntest\\r\\n\" > test\n+'\n+\n+test_expect_success 'add without --no-filters' '\n+\toriginal=\"$(git hash-object --stdin < test)\" &&\n+\tconverted=\"$(git hash-object test)\" &&\n+\tgit add test &&\n+\tgit ls-files -s > actual &&\n+\tcat > expected <<-EOF &&\n+\t100644 $(git hash-object .gitattributes) 0\t.gitattributes\n+\t100644 $converted 0\ttest\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'add with --no-filters' '\n+\tgit rm -f --cached test &&\n+\toriginal=\"$(git hash-object --stdin < test)\" &&\n+\tconverted=\"$(git hash-object test)\" &&\n+\tgit add --no-filters test &&\n+\tgit ls-files -s > actual &&\n+\tcat > expected <<-EOF &&\n+\t100644 $(git hash-object .gitattributes) 0\t.gitattributes\n+\t100644 $original 0\ttest\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n+test_done\n-- \ngitgitgadget\n\n"},{"id":"417414","messageId":"0e113e958b3514d2579eb46c1005fd7b26e0a077.1613758333.git.gitgitgadget@gmail.com","threadId":"55175","inReplyTo":"pull.880.git.1613758333.gitgitgadget@gmail.com","subject":"[PATCH 2/2] hash-object: use the new HASH_RAW flag instead of setting path to NULL","fromName":"Andrej Shadura via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-19T18:12:13Z","receivedAt":"2021-02-19T18:13:00Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"From: Andrej Shadura <andrew.shadura@collabora.co.uk>\n\nWhile setting path to NULL works and flips the condition in the right\nbranch inside index_mem(), doing so isn’t obvious for the reader of\nthe code. Since index_mem() now has an additional flag to disable\nfiltering, use that instead.\n\nSigned-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>\n---\n builtin/hash-object.c | 17 +++++++----------\n 1 file changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 640ef4ded595..8e0543b12bc5 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -59,8 +59,7 @@ static void hash_object(const char *path, const char *type, const char *vpath,\n \thash_fd(fd, type, vpath, flags, literally);\n }\n \n-static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,\n-\t\t\t     int literally)\n+static void hash_stdin_paths(const char *type, unsigned flags, int literally)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct strbuf unquoted = STRBUF_INIT;\n@@ -72,8 +71,7 @@ static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,\n \t\t\t\tdie(\"line is badly quoted\");\n \t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t}\n-\t\thash_object(buf.buf, type, no_filters ? NULL : buf.buf, flags,\n-\t\t\t    literally);\n+\t\thash_object(buf.buf, type, buf.buf, flags, literally);\n \t}\n \tstrbuf_release(&buf);\n \tstrbuf_release(&unquoted);\n@@ -89,7 +87,6 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \tconst char *type = blob_type;\n \tint hashstdin = 0;\n \tint stdin_paths = 0;\n-\tint no_filters = 0;\n \tint literally = 0;\n \tint nongit = 0;\n \tunsigned flags = HASH_FORMAT_CHECK;\n@@ -100,7 +97,8 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \t\t\tHASH_WRITE_OBJECT),\n \t\tOPT_COUNTUP( 0 , \"stdin\", &hashstdin, N_(\"read the object from stdin\")),\n \t\tOPT_BOOL( 0 , \"stdin-paths\", &stdin_paths, N_(\"read file names from stdin\")),\n-\t\tOPT_BOOL( 0 , \"no-filters\", &no_filters, N_(\"store file as is without filters\")),\n+\t\tOPT_BIT(0 , \"no-filters\", &flags, N_(\"store file as is without filters\"),\n+\t\t\tHASH_RAW),\n \t\tOPT_BOOL( 0, \"literally\", &literally, N_(\"just hash any random garbage to create corrupt objects for debugging Git\")),\n \t\tOPT_STRING( 0 , \"path\", &vpath, N_(\"file\"), N_(\"process file as it were from this path\")),\n \t\tOPT_END()\n@@ -132,7 +130,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \telse {\n \t\tif (hashstdin > 1)\n \t\t\terrstr = \"Multiple --stdin arguments are not supported\";\n-\t\tif (vpath && no_filters)\n+\t\tif (vpath && (flags & HASH_RAW))\n \t\t\terrstr = \"Can't use --path with --no-filters\";\n \t}\n \n@@ -150,13 +148,12 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \n \t\tif (prefix)\n \t\t\targ = to_free = prefix_filename(prefix, arg);\n-\t\thash_object(arg, type, no_filters ? NULL : vpath ? vpath : arg,\n-\t\t\t    flags, literally);\n+\t\thash_object(arg, type, vpath ? vpath : arg, flags, literally);\n \t\tfree(to_free);\n \t}\n \n \tif (stdin_paths)\n-\t\thash_stdin_paths(type, no_filters, flags, literally);\n+\t\thash_stdin_paths(type, flags, literally);\n \n \treturn 0;\n }\n-- \ngitgitgadget\n"},{"id":"417422","messageId":"YDA9WjWOjkqlsALc@camp.crustytoothpaste.net","threadId":"55175","inReplyTo":"pull.880.git.1613758333.gitgitgadget@gmail.com","subject":"Re: [PATCH 0/2] Add --no-filters option to git-add","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2021-02-19T22:36:10Z","receivedAt":"2021-02-19T22:37:41Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2021-02-19 at 18:12:11, Andrej Shadura via GitGitGadget wrote:\n> It is possible for a user to disable attribute-based filtering when\n> committing by doing one of the following:\n> \n>  * Create .git/info/attributes unapplying all possible transforming\n>    attributes.\n>  * Use git hash-object and git update-index to stage files manually.\n> \n> Doing the former requires keeping an up-to-date list of all attributes which\n> can transform files when committing or checking out. Doing the latter is\n> difficult, error-prone and slow when done from scripts.\n> \n> Instead, similarly to git hash-object, --no-filter can be added to git add\n> to enable temporarily disabling filtering in an easy to use way.\n> \n> These patches:\n> \n>  * Add new flag ADD_CACHE_RAW to add_to_index()\n>  * Add new flag HASH_RAW to index_fd()\n>  * Make git hash-object use the new HASH_RAW flag for consistency\n>  * Add tests for the new git-add option.\n\nI'm interested in your use cases here.  While I agree that this is an\ninteresting feature, it also means that practically, a user who checks\nout a file that's added this way may find that git status marks it as\nperpetually modified until a properly cleaned version is committed.\nMoreover, even \"git reset --hard\" won't fix this situation.\n\nWe see this problem extremely frequently with Git LFS where people\nchange the .gitattributes file but don't run \"git add --renormalize .\"\nand then end up with this problem.  However, it's not limited to Git LFS\nin particular; anything that uses filters, working tree encodings, or\nend of line attributes can be affected.\n\nSo I think that while this might be a useful escape hatch for users, I\ndefinitely want to see a compelling rationale for it and a big warning\nin the documentation and an update to the relevant entry in the Git FAQ\nbefore we accept such a patch.\n-- \nbrian m. carlson (he/him or they/them)\nHouston, Texas, US\n"},{"id":"417437","messageId":"a58d8057-9847-ba57-1bf5-5d27c235d210@collabora.co.uk","threadId":"55175","inReplyTo":"YDA9WjWOjkqlsALc@camp.crustytoothpaste.net","subject":"Re: [PATCH 0/2] Add --no-filters option to git-add","fromName":"Andrej Shadura","fromEmail":"andrew.shadura@collabora.co.uk","sentAt":"2021-02-20T08:06:10Z","receivedAt":"2021-02-20T08:07:17Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"On 19/02/2021 23:36, brian m. carlson wrote:\n> On 2021-02-19 at 18:12:11, Andrej Shadura via GitGitGadget wrote:\n>> It is possible for a user to disable attribute-based filtering when\n>> committing by doing one of the following:\n>>\n>>  * Create .git/info/attributes unapplying all possible transforming\n>>    attributes.\n>>  * Use git hash-object and git update-index to stage files manually.\n>>\n>> Doing the former requires keeping an up-to-date list of all attributes which\n>> can transform files when committing or checking out. Doing the latter is\n>> difficult, error-prone and slow when done from scripts.\n>>\n>> Instead, similarly to git hash-object, --no-filter can be added to git add\n>> to enable temporarily disabling filtering in an easy to use way.\n\n> I'm interested in your use cases here.  While I agree that this is an\n> interesting feature, it also means that practically, a user who checks\n> out a file that's added this way may find that git status marks it as\n> perpetually modified until a properly cleaned version is committed.\n> Moreover, even \"git reset --hard\" won't fix this situation.\n> \n> We see this problem extremely frequently with Git LFS where people\n> change the .gitattributes file but don't run \"git add --renormalize .\"\n> and then end up with this problem.  However, it's not limited to Git LFS\n> in particular; anything that uses filters, working tree encodings, or\n> end of line attributes can be affected.\n> \n> So I think that while this might be a useful escape hatch for users, I\n> definitely want to see a compelling rationale for it and a big warning\n> in the documentation and an update to the relevant entry in the Git FAQ\n> before we accept such a patch.\n\nMy use case here is mostly non-interactive use in scripts creating Git\ntrees that need to exactly correspond to a working directory regardless\nof whether or not they have any .gitattributes files.\n\nFor example, for git-buildpackage or dgit, which facilitate Git\nworkflows with Debian packages, want to ensure the contents of the\npackages can be exactly reproduced, which is difficult if the upstream’s\ntarball has .gitattributes. It is possible to \"defuse\" the attributes as\ndemonstrated above, but this will break if the user modifies the\n.git/i/a file *or* if Git adds more attribute-based conversions. This is\nwhat dgit currently does, and this is what git-buildpackage will soon do\ntoo.\n\nOf course, this patch set only addresses staging files. While working on\na patch to git-buildpackage to reproducibly import the contents of\ntarballs, I realised that the only realistic way seem to do that is to\nuse hash-object + update-index manually, which is likely to come with a\nperformance drop compared to git add (which is what gbp currently uses).\nA workaround might be to use dulwich (which would allow to do\nhash-object without fork/exec) or perhaps GitPython (which I haven’t\nreally looked into), or maybe to use git fast-import, but all of these\nalternatives are quite complex and don’t guarantee the same performance.\n\nAdding a new option to git add allows to keep the performance without\nhaving to ensure attributes are set to the right values. The attributes\nwill likely have to be adjusted anyway for user’s convenience, but at\nleast if they modify them afterwards, the tools won’t break.\n\n-- \nCheers,\n  Andrej\n"},{"id":"417438","messageId":"c660bf7b-cd59-43d4-a374-11997f0b15d1@collabora.co.uk","threadId":"55175","inReplyTo":"a58d8057-9847-ba57-1bf5-5d27c235d210@collabora.co.uk","subject":"Re: [PATCH 0/2] Add --no-filters option to git-add","fromName":"Andrej Shadura","fromEmail":"andrew.shadura@collabora.co.uk","sentAt":"2021-02-20T09:30:58Z","receivedAt":"2021-02-20T09:31:47Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"On 20/02/2021 09:06, Andrej Shadura wrote:\n> On 19/02/2021 23:36, brian m. carlson wrote:\n>> So I think that while this might be a useful escape hatch for users, I\n>> definitely want to see a compelling rationale for it and a big warning\n>> in the documentation and an update to the relevant entry in the Git FAQ\n>> before we accept such a patch.\n\nHere’s my proposal for the updated manpage description of the option:\n\n--no-filters::\n\nAdd the contents as is, ignoring any input filter that would have been\nchosen by the attributes mechanism, including the end-of-line\nconversion. Note that this option is not intended for interactive use,\nsince files added this way will always show up as modified if Git were\nto apply transformations to them, making the situation potentially very\nconfusing.\n\nAnd here the FAQ entry extended:\n\nIt is also possible for perpetually modified files to occur on any\nplatform if a smudge or clean filter is in use on your system but a file\nwas previously committed without running the smudge or clean filter.  To\nfix this, run the following on an otherwise clean working tree:\n+\n----\n$ git add --renormalize .\n----\n+\nAnother situation where perpetually modified may appear on any platform\nis when a file has been committed without running any filters (including\nthe end-of-line conversion), but the `.gitattributes` file states that\nthis file requires a conversion.  In this case, you can either\nrenormalize the files if this happened by mistake, or modify\n`.gitattributes` or `$GIT_DIR/info/attributes` as described above to\nexempt the file from the conversion if this was intentional.\n\n(I will send an updated patch set when we agree on the wording.)\n\n-- \nCheers,\n  Andrej\n"},{"id":"417441","messageId":"YDEYaVibMFo1OJZs@camp.crustytoothpaste.net","threadId":"55175","inReplyTo":"c660bf7b-cd59-43d4-a374-11997f0b15d1@collabora.co.uk","subject":"Re: [PATCH 0/2] Add --no-filters option to git-add","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2021-02-20T14:10:49Z","receivedAt":"2021-02-20T14:11:53Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2021-02-20 at 09:30:58, Andrej Shadura wrote:\n> On 20/02/2021 09:06, Andrej Shadura wrote:\n> > On 19/02/2021 23:36, brian m. carlson wrote:\n> >> So I think that while this might be a useful escape hatch for users, I\n> >> definitely want to see a compelling rationale for it and a big warning\n> >> in the documentation and an update to the relevant entry in the Git FAQ\n> >> before we accept such a patch.\n> \n> Here’s my proposal for the updated manpage description of the option:\n> \n> --no-filters::\n> \n> Add the contents as is, ignoring any input filter that would have been\n> chosen by the attributes mechanism, including the end-of-line\n> conversion. Note that this option is not intended for interactive use,\n> since files added this way will always show up as modified if Git were\n> to apply transformations to them, making the situation potentially very\n> confusing.\n> \n> And here the FAQ entry extended:\n> \n> It is also possible for perpetually modified files to occur on any\n> platform if a smudge or clean filter is in use on your system but a file\n> was previously committed without running the smudge or clean filter.  To\n> fix this, run the following on an otherwise clean working tree:\n> +\n> ----\n> $ git add --renormalize .\n> ----\n> +\n> Another situation where perpetually modified may appear on any platform\n> is when a file has been committed without running any filters (including\n> the end-of-line conversion), but the `.gitattributes` file states that\n> this file requires a conversion.  In this case, you can either\n> renormalize the files if this happened by mistake, or modify\n> `.gitattributes` or `$GIT_DIR/info/attributes` as described above to\n> exempt the file from the conversion if this was intentional.\n> \n> (I will send an updated patch set when we agree on the wording.)\n\nThis seems fine.  Thanks for being open to addressing my concerns, and I\nagree that your use case seems like a good one and that this is a\nvaluable feature.\n-- \nbrian m. carlson (he/him or they/them)\nHouston, Texas, US\n"},{"id":"417444","messageId":"pull.880.v2.git.1613840865.gitgitgadget@gmail.com","threadId":"55175","inReplyTo":"pull.880.git.1613758333.gitgitgadget@gmail.com","subject":"[PATCH v2 0/2] Add --no-filters option to git-add","fromName":"Andrej Shadura via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-20T17:07:43Z","receivedAt":"2021-02-20T17:08:56Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"It is possible for a user to disable attribute-based filtering when\ncommitting by doing one of the following:\n\n * Create .git/info/attributes unapplying all possible transforming\n   attributes.\n * Use git hash-object and git update-index to stage files manually.\n\nDoing the former requires keeping an up-to-date list of all attributes which\ncan transform files when committing or checking out. Doing the latter is\ndifficult, error-prone and slow when done from scripts.\n\nInstead, similarly to git hash-object, --no-filter can be added to git add\nto enable temporarily disabling filtering in an easy to use way.\n\nThe use case here is mostly non-interactive use in scripts creating Git\ntrees that need to exactly correspond to a working directory regardless of\nwhether or not they have any .gitattributes files.\n\nFor example, for git-buildpackage or dgit, which facilitate Git workflows\nwith Debian packages, want to ensure the contents of the packages can be\nexactly reproduced, which is difficult if the upstream’s tarball has\n.gitattributes. It is possible to \"defuse\" the attributes as demonstrated\nabove, but this will break if the user modifies the .git/i/a file or if Git\nadds more attribute-based conversions. This is what dgit currently does, and\nthis is what git-buildpackage will soon do too.\n\nOf course, this patch set only addresses staging files. While working on a\npatch to git-buildpackage to reproducibly import the contents of tarballs, I\nrealised that the only realistic way seem to do that is to use hash-object +\nupdate-index manually, which is likely to come with a performance drop\ncompared to git add (which is what gbp currently uses). A workaround might\nbe to use Dulwich (which would allow to do hash-object without fork/exec) or\nperhaps GitPython (which I haven’t really looked into), or maybe to use git\nfast-import, but all of these alternatives are quite complex and don’t\nguarantee the same performance.\n\nAdding a new option to git add allows to keep the performance without having\nto ensure attributes are set to the right values. The attributes will likely\nhave to be adjusted anyway for user’s convenience, but at least if they\nmodify them afterwards, the tools won’t break.\n\nThese patches:\n\n * Add new flag ADD_CACHE_RAW to add_to_index()\n * Add new flag HASH_RAW to index_fd()\n * Make git hash-object use the new HASH_RAW flag for consistency\n * Add tests for the new git-add option.\n * Update the git-add manpage describing the new option and pointing out\n   it’s tricky to use.\n * Expand the relevant FAQ entry adding --no-filters as yet one more reason\n   for perpetually modified files to appear.\n\nChanges since v1:\n\n * Removed an extra space left in the option definition. Jessica Clarke on\n   GitHub pointed out the inconsistent formatting, but contrary to the\n   suggestion I updated the style to the more widespread variation: \"(0,\"\n   occurs at least 689 times across the codebase, while \"( 0\" only at most\n   23.\n * Expanded the option description to warn users about potentially confusing\n   situations (pointed out by brian m. carlson)\n * Expanded the FAQ entry to mention the new option as one of the cause of\n   perpetually modified files.\n\nAndrej Shadura (2):\n  add: add option --no-filters to disable attribute-based filtering\n  hash-object: use the new HASH_RAW flag instead of setting path to NULL\n\n Documentation/git-add.txt | 10 ++++++++-\n Documentation/gitfaq.txt  |  7 ++++++\n builtin/add.c             |  3 +++\n builtin/hash-object.c     | 17 ++++++---------\n cache.h                   |  2 ++\n object-file.c             |  2 +-\n read-cache.c              |  3 +++\n t/t2205-add-no-filters.sh | 46 +++++++++++++++++++++++++++++++++++++++\n 8 files changed, 78 insertions(+), 12 deletions(-)\n create mode 100755 t/t2205-add-no-filters.sh\n\n\nbase-commit: 2283e0e9af55689215afa39c03beb2315ce18e83\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-880%2Fandrewshadura%2Fgit-add-no-filters-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-880/andrewshadura/git-add-no-filters-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/880\n\nRange-diff vs v1:\n\n 1:  cf8eb886a1e2 ! 1:  1d84503fff48 add: add option --no-filters to disable attribute-based filtering\n     @@ Documentation/git-add.txt: for \"git add --no-all <pathspec>...\", i.e. ignored re\n      +--no-filters::\n      +\tAdd the contents as is, ignoring any input filter that would\n      +\thave been chosen by the attributes mechanism, including the end-of-line\n     -+\tconversion.\n     ++\tconversion. Note that this option is not intended for interactive use,\n     ++\tsince files added this way will always show up as modified if Git were\n     ++\tto apply transformations to them, making the situation potentially\n     ++\tvery confusing.\n      +\n       --chmod=(+|-)x::\n       \tOverride the executable bit of the added files.  The executable\n       \tbit is only changed in the index, the files on disk are left\n      \n     + ## Documentation/gitfaq.txt ##\n     +@@ Documentation/gitfaq.txt: following on an otherwise clean working tree:\n     + ----\n     + $ git add --renormalize .\n     + ----\n     +++\n     ++Another situation where perpetually modified may appear on any platform is when\n     ++a file has been committed without running any filters (including the end-of-line\n     ++conversion), but the `.gitattributes` file states that this file requires a\n     ++conversion.  In this case, you can either renormalize the files if this happened\n     ++by mistake, or modify `.gitattributes` or `$GIT_DIR/info/attributes` as described\n     ++above to exempt the file from the conversion if this was intentional.\n     + \n     + [[recommended-storage-settings]]\n     + What's the recommended way to store files in Git?::\n     +\n       ## builtin/add.c ##\n      @@ builtin/add.c: static const char * const builtin_add_usage[] = {\n       static int patch_interactive, add_interactive, edit_interactive;\n 2:  0e113e958b35 ! 2:  810d4005fe8f hash-object: use the new HASH_RAW flag instead of setting path to NULL\n     @@ builtin/hash-object.c: int cmd_hash_object(int argc, const char **argv, const ch\n       \t\tOPT_COUNTUP( 0 , \"stdin\", &hashstdin, N_(\"read the object from stdin\")),\n       \t\tOPT_BOOL( 0 , \"stdin-paths\", &stdin_paths, N_(\"read file names from stdin\")),\n      -\t\tOPT_BOOL( 0 , \"no-filters\", &no_filters, N_(\"store file as is without filters\")),\n     -+\t\tOPT_BIT(0 , \"no-filters\", &flags, N_(\"store file as is without filters\"),\n     ++\t\tOPT_BIT(0, \"no-filters\", &flags, N_(\"store file as is without filters\"),\n      +\t\t\tHASH_RAW),\n       \t\tOPT_BOOL( 0, \"literally\", &literally, N_(\"just hash any random garbage to create corrupt objects for debugging Git\")),\n       \t\tOPT_STRING( 0 , \"path\", &vpath, N_(\"file\"), N_(\"process file as it were from this path\")),\n\n-- \ngitgitgadget\n"},{"id":"417445","messageId":"1d84503fff481910a4ae6eb86fa6f77afc2b3d95.1613840865.git.gitgitgadget@gmail.com","threadId":"55175","inReplyTo":"pull.880.v2.git.1613840865.gitgitgadget@gmail.com","subject":"[PATCH v2 1/2] add: add option --no-filters to disable attribute-based filtering","fromName":"Andrej Shadura via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-20T17:07:44Z","receivedAt":"2021-02-20T17:08:56Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"From: Andrej Shadura <andrew.shadura@collabora.co.uk>\n\nIt is possible for a user to disable attribute-based filtering when\ncommitting by doing one of the following:\n\n* Create .git/info/attributes unapplying all possible transforming\n  attributes.\n* Use git hash-object and git update-index to stage files manually.\n\nDoing the former requires keeping an up-to-date list of all attributes\nwhich can transform files when committing or checking out.\nDoing the latter is difficult, error-prone and slow when done from\nscripts.\n\nInstead, similarly to git hash-object, --no-filter can be added to\ngit add to enable temporarily disabling filtering in an easy to use\nway:\n\n* Add new flag ADD_CACHE_RAW to add_to_index()\n* Add new flag HASH_RAW to index_fd()\n\nSigned-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>\n---\n Documentation/git-add.txt | 10 ++++++++-\n Documentation/gitfaq.txt  |  7 ++++++\n builtin/add.c             |  3 +++\n cache.h                   |  2 ++\n object-file.c             |  2 +-\n read-cache.c              |  3 +++\n t/t2205-add-no-filters.sh | 46 +++++++++++++++++++++++++++++++++++++++\n 7 files changed, 71 insertions(+), 2 deletions(-)\n create mode 100755 t/t2205-add-no-filters.sh\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex be5e3ac54b85..75b474a88fca 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]\n-\t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n+\t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--no-filters]\n \t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize]\n \t  [--chmod=(+|-)x] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n \t  [--] [<pathspec>...]\n@@ -183,6 +183,14 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n \tin order to correct files added with wrong CRLF/LF line endings.\n \tThis option implies `-u`.\n \n+--no-filters::\n+\tAdd the contents as is, ignoring any input filter that would\n+\thave been chosen by the attributes mechanism, including the end-of-line\n+\tconversion. Note that this option is not intended for interactive use,\n+\tsince files added this way will always show up as modified if Git were\n+\tto apply transformations to them, making the situation potentially\n+\tvery confusing.\n+\n --chmod=(+|-)x::\n \tOverride the executable bit of the added files.  The executable\n \tbit is only changed in the index, the files on disk are left\ndiff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt\nindex afdaeab8503c..6011abca0bea 100644\n--- a/Documentation/gitfaq.txt\n+++ b/Documentation/gitfaq.txt\n@@ -395,6 +395,13 @@ following on an otherwise clean working tree:\n ----\n $ git add --renormalize .\n ----\n++\n+Another situation where perpetually modified may appear on any platform is when\n+a file has been committed without running any filters (including the end-of-line\n+conversion), but the `.gitattributes` file states that this file requires a\n+conversion.  In this case, you can either renormalize the files if this happened\n+by mistake, or modify `.gitattributes` or `$GIT_DIR/info/attributes` as described\n+above to exempt the file from the conversion if this was intentional.\n \n [[recommended-storage-settings]]\n What's the recommended way to store files in Git?::\ndiff --git a/builtin/add.c b/builtin/add.c\nindex a825887c503d..609a0e6c0157 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -29,6 +29,7 @@ static const char * const builtin_add_usage[] = {\n static int patch_interactive, add_interactive, edit_interactive;\n static int take_worktree_changes;\n static int add_renormalize;\n+static int no_filters;\n static int pathspec_file_nul;\n static const char *pathspec_from_file;\n static int legacy_stash_p; /* support for the scripted `git stash` */\n@@ -334,6 +335,7 @@ static struct option builtin_add_options[] = {\n \tOPT__FORCE(&ignored_too, N_(\"allow adding otherwise ignored files\"), 0),\n \tOPT_BOOL('u', \"update\", &take_worktree_changes, N_(\"update tracked files\")),\n \tOPT_BOOL(0, \"renormalize\", &add_renormalize, N_(\"renormalize EOL of tracked files (implies -u)\")),\n+\tOPT_BOOL(0 , \"no-filters\", &no_filters, N_(\"store file as is without filters\")),\n \tOPT_BOOL('N', \"intent-to-add\", &intent_to_add, N_(\"record only the fact that the path will be added later\")),\n \tOPT_BOOL('A', \"all\", &addremove_explicit, N_(\"add changes from all tracked and untracked files\")),\n \tOPT_CALLBACK_F(0, \"ignore-removal\", &addremove_explicit,\n@@ -531,6 +533,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t (show_only ? ADD_CACHE_PRETEND : 0) |\n \t\t (intent_to_add ? ADD_CACHE_INTENT : 0) |\n \t\t (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |\n+\t\t (no_filters ? ADD_CACHE_RAW : 0) |\n \t\t (!(addremove || take_worktree_changes)\n \t\t  ? ADD_CACHE_IGNORE_REMOVAL : 0));\n \ndiff --git a/cache.h b/cache.h\nindex d92814961405..df83b5709c32 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -820,6 +820,7 @@ int remove_file_from_index(struct index_state *, const char *path);\n #define ADD_CACHE_IGNORE_ERRORS\t4\n #define ADD_CACHE_IGNORE_REMOVAL 8\n #define ADD_CACHE_INTENT 16\n+#define ADD_CACHE_RAW 32\n /*\n  * These two are used to add the contents of the file at path\n  * to the index, marking the working tree up-to-date by storing\n@@ -858,6 +859,7 @@ int ie_modified(struct index_state *, const struct cache_entry *, struct stat *,\n #define HASH_WRITE_OBJECT 1\n #define HASH_FORMAT_CHECK 2\n #define HASH_RENORMALIZE  4\n+#define HASH_RAW          8\n int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);\n int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags);\n \ndiff --git a/object-file.c b/object-file.c\nindex 5bcfde847188..74487c22e586 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2067,7 +2067,7 @@ static int index_mem(struct index_state *istate,\n \t/*\n \t * Convert blobs to git internal format\n \t */\n-\tif ((type == OBJ_BLOB) && path) {\n+\tif ((type == OBJ_BLOB) && path && !(flags & HASH_RAW)) {\n \t\tstruct strbuf nbuf = STRBUF_INIT;\n \t\tif (convert_to_git(istate, path, buf, size, &nbuf,\n \t\t\t\t   get_conv_flags(flags))) {\ndiff --git a/read-cache.c b/read-cache.c\nindex 29144cf879e7..0fb31201c705 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -716,6 +716,9 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \tif (flags & ADD_CACHE_RENORMALIZE)\n \t\thash_flags |= HASH_RENORMALIZE;\n \n+\tif (flags & ADD_CACHE_RAW)\n+\t\thash_flags |= HASH_RAW;\n+\n \tif (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))\n \t\treturn error(_(\"%s: can only add regular files, symbolic links or git-directories\"), path);\n \ndiff --git a/t/t2205-add-no-filters.sh b/t/t2205-add-no-filters.sh\nnew file mode 100755\nindex 000000000000..a897ed810827\n--- /dev/null\n+++ b/t/t2205-add-no-filters.sh\n@@ -0,0 +1,46 @@\n+#!/bin/sh\n+\n+test_description='git add --no-filters\n+\n+This test creates a file and a corresponding .gitattributes setup\n+to ensure the file undergoes a conversion when committed or checked\n+out.\n+\n+It then verifies that the conversion happens by default, but does not\n+when --no-filters is used.'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo \"* eol=crlf\" > .gitattributes &&\n+\tgit add .gitattributes &&\n+\tgit commit -m initial &&\n+\tprintf \"test\\r\\ntest\\r\\n\" > test\n+'\n+\n+test_expect_success 'add without --no-filters' '\n+\toriginal=\"$(git hash-object --stdin < test)\" &&\n+\tconverted=\"$(git hash-object test)\" &&\n+\tgit add test &&\n+\tgit ls-files -s > actual &&\n+\tcat > expected <<-EOF &&\n+\t100644 $(git hash-object .gitattributes) 0\t.gitattributes\n+\t100644 $converted 0\ttest\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'add with --no-filters' '\n+\tgit rm -f --cached test &&\n+\toriginal=\"$(git hash-object --stdin < test)\" &&\n+\tconverted=\"$(git hash-object test)\" &&\n+\tgit add --no-filters test &&\n+\tgit ls-files -s > actual &&\n+\tcat > expected <<-EOF &&\n+\t100644 $(git hash-object .gitattributes) 0\t.gitattributes\n+\t100644 $original 0\ttest\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n+test_done\n-- \ngitgitgadget\n\n"},{"id":"417446","messageId":"810d4005fe8f018e7e8e179cbd005cc203b06441.1613840865.git.gitgitgadget@gmail.com","threadId":"55175","inReplyTo":"pull.880.v2.git.1613840865.gitgitgadget@gmail.com","subject":"[PATCH v2 2/2] hash-object: use the new HASH_RAW flag instead of setting path to NULL","fromName":"Andrej Shadura via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-20T17:07:45Z","receivedAt":"2021-02-20T17:08:56Z","isPatch":true,"sender":{"key":"andrew.shadura@collabora.co.uk","avatar":"https://gravatar.com/avatar/b8a2e566757c079bac2d71b7bab3f11eb3472ab8a1ddfc8aaf8e957db8d6249f?d=mp&s=160"},"body":"From: Andrej Shadura <andrew.shadura@collabora.co.uk>\n\nWhile setting path to NULL works and flips the condition in the right\nbranch inside index_mem(), doing so isn’t obvious for the reader of\nthe code. Since index_mem() now has an additional flag to disable\nfiltering, use that instead.\n\nSigned-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>\n---\n builtin/hash-object.c | 17 +++++++----------\n 1 file changed, 7 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/hash-object.c b/builtin/hash-object.c\nindex 640ef4ded595..6f261a1f00e3 100644\n--- a/builtin/hash-object.c\n+++ b/builtin/hash-object.c\n@@ -59,8 +59,7 @@ static void hash_object(const char *path, const char *type, const char *vpath,\n \thash_fd(fd, type, vpath, flags, literally);\n }\n \n-static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,\n-\t\t\t     int literally)\n+static void hash_stdin_paths(const char *type, unsigned flags, int literally)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct strbuf unquoted = STRBUF_INIT;\n@@ -72,8 +71,7 @@ static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,\n \t\t\t\tdie(\"line is badly quoted\");\n \t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t}\n-\t\thash_object(buf.buf, type, no_filters ? NULL : buf.buf, flags,\n-\t\t\t    literally);\n+\t\thash_object(buf.buf, type, buf.buf, flags, literally);\n \t}\n \tstrbuf_release(&buf);\n \tstrbuf_release(&unquoted);\n@@ -89,7 +87,6 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \tconst char *type = blob_type;\n \tint hashstdin = 0;\n \tint stdin_paths = 0;\n-\tint no_filters = 0;\n \tint literally = 0;\n \tint nongit = 0;\n \tunsigned flags = HASH_FORMAT_CHECK;\n@@ -100,7 +97,8 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \t\t\tHASH_WRITE_OBJECT),\n \t\tOPT_COUNTUP( 0 , \"stdin\", &hashstdin, N_(\"read the object from stdin\")),\n \t\tOPT_BOOL( 0 , \"stdin-paths\", &stdin_paths, N_(\"read file names from stdin\")),\n-\t\tOPT_BOOL( 0 , \"no-filters\", &no_filters, N_(\"store file as is without filters\")),\n+\t\tOPT_BIT(0, \"no-filters\", &flags, N_(\"store file as is without filters\"),\n+\t\t\tHASH_RAW),\n \t\tOPT_BOOL( 0, \"literally\", &literally, N_(\"just hash any random garbage to create corrupt objects for debugging Git\")),\n \t\tOPT_STRING( 0 , \"path\", &vpath, N_(\"file\"), N_(\"process file as it were from this path\")),\n \t\tOPT_END()\n@@ -132,7 +130,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \telse {\n \t\tif (hashstdin > 1)\n \t\t\terrstr = \"Multiple --stdin arguments are not supported\";\n-\t\tif (vpath && no_filters)\n+\t\tif (vpath && (flags & HASH_RAW))\n \t\t\terrstr = \"Can't use --path with --no-filters\";\n \t}\n \n@@ -150,13 +148,12 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)\n \n \t\tif (prefix)\n \t\t\targ = to_free = prefix_filename(prefix, arg);\n-\t\thash_object(arg, type, no_filters ? NULL : vpath ? vpath : arg,\n-\t\t\t    flags, literally);\n+\t\thash_object(arg, type, vpath ? vpath : arg, flags, literally);\n \t\tfree(to_free);\n \t}\n \n \tif (stdin_paths)\n-\t\thash_stdin_paths(type, no_filters, flags, literally);\n+\t\thash_stdin_paths(type, flags, literally);\n \n \treturn 0;\n }\n-- \ngitgitgadget\n"},{"id":"417448","messageId":"xmqq4ki6a0ex.fsf@gitster.g","threadId":"55175","inReplyTo":"pull.880.v2.git.1613840865.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/2] Add --no-filters option to git-add","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-02-20T21:34:30Z","receivedAt":"2021-02-20T21:35:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Andrej Shadura via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> It is possible for a user to disable attribute-based filtering when\n> committing by doing one of the following:\n>\n>  * Create .git/info/attributes unapplying all possible transforming\n>    attributes.\n>  * Use git hash-object and git update-index to stage files manually.\n>\n> Doing the former requires keeping an up-to-date list of all attributes which\n> can transform files when committing or checking out. Doing the latter is\n> difficult, error-prone and slow when done from scripts.\n>\n> Instead, similarly to git hash-object, --no-filter can be added to git add\n> to enable temporarily disabling filtering in an easy to use way.\n\nI think brian's review covered if such a feature is desirable to\nsufficient level, and I do not have anything to add in that area,\nso I'll limit my comment to the general design and implementation.\n\nIn general, think three times before introducing --no-something\noption.  It often is much cleaner and futureproof if you instead\nintroduced --something option whose value defaults to true instead,\nso that the end-user can say --no-something from the command line.\n\n\n>       -\t\tOPT_BOOL( 0 , \"no-filters\", &no_filters, N_(\"store file as is without filters\")),\n>      -+\t\tOPT_BIT(0 , \"no-filters\", &flags, N_(\"store file as is without filters\"),\n>      ++\t\tOPT_BIT(0, \"no-filters\", &flags, N_(\"store file as is without filters\"),\n>       +\t\t\tHASH_RAW),\n\nIn other words, these should give \"filters\" option, and the code\nshould initialize the flags word with USE_CLEAN_FILTER bit on by\ndefault (the use of \"clean\" here comes from \"clean vs smudge\", one\nof the pair of filters end-user can customize the path the data\ntakes going into Git from the outside world; and the \"clean\" and\n\"smudge\" datapaths also trigger non-custom standard ones like crlf\nmunging).\n\nThat way when a configuration variable support is introduced to\nallow the users to say \"I by default refuse to use the clean filters\nwhen running 'git add'\" by setting say \"[add] cleanfilter = false\",\nthe user can override that with \"--filters\" from the command line\n\"for just this time\".  The same goes for an alias that hardcodes\n\"--no-filters\" on the command line, where allowing \"--filters\" lets\nthe users override it.\n\nThanks.\n"}]}