{"thread":{"id":"14889","subject":"How to fix (and find) many git-* --check errors?","startedAt":"2008-08-08T12:49:00Z","lastAt":"2008-08-09T07:28:59Z","messageCount":6,"participants":["Peter Valdemar Mørch (Lists)","Jeff King","Björn Steinbrink","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"86493","messageId":"489C40BC.8000008@sneakemail.com","threadId":"14889","inReplyTo":null,"subject":"How to fix (and find) many git-* --check errors?","fromName":"Peter Valdemar Mørch (Lists)","fromEmail":"4ux6as402@sneakemail.com","sentAt":"2008-08-08T12:49:00Z","receivedAt":"2008-08-08T12:49:00Z","isPatch":false,"sender":{"key":"4ux6as402@sneakemail.com","avatar":null},"body":"We have > 37000 white space \"errors\" in HEAD, mostly trailing \nwhitespace, and I'm looking for a\n\n$ git diff --check | git??? --whitespace=fix\n\ncommand.\n\nIs there such a beast?\n\nI see that git-apply has a --whitespace=<action> option, but I don't \nseem to grock how to be able to use it for fixing my working directory.\n\nDetails follow:\n\nI can create a perl script that does this for me (e.g. inspired by \n1.5.6's hooks/pre-commit's perl version of git diff --check) and post it \nhere if anybody would like it, but I'd rather use some well-tested \nmethod if one exists. And it seems git-apply has the functionality somehow.\n\nOf course, I can also:\n\n$ git diff --check > tmpcfile\n# (Or some other command to find all of them under ./)\n$ vim\n:cfile tmpcfile\n\nThank you for --check having a handy output format, BTW! But I prefer \nautomation (and automated auditing of the results) for 37000 lines.\n\nAlso the way I found them is like this:\n\n$ git diff --check $(git log --pretty=format:%H | tail -1)..HEAD .\n\n(The diff between \"the empty commit\" and HEAD - well between the first \ncommit and HEAD anyway. Is there a ref for \"totally empty\" or the \nrevision before the first commit? Or a more elegant way to get this list?)\n\nPeter\n-- \nPeter Valdemar Mørch\nhttp://www.morch.com\n"},{"id":"86496","messageId":"20080808132326.GC19705@sigill.intra.peff.net","threadId":"14889","inReplyTo":"489C40BC.8000008@sneakemail.com","subject":"Re: How to fix (and find) many git-* --check errors?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-08-08T13:23:26Z","receivedAt":"2008-08-08T13:23:26Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Aug 08, 2008 at 02:49:00PM +0200, \"Peter Valdemar Mørch (Lists)\" wrote:\n\n> (The diff between \"the empty commit\" and HEAD - well between the first\n> commit and HEAD anyway. Is there a ref for \"totally empty\" or the\n> revision before the first commit? Or a more elegant way to get this\n> list?)\n\nIt is not advertised, but we always recognize the empty sha1 of the\nempty tree:\n\n  git diff --check 4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\nIn fact, just the other day I was using this for the Nth time and got\ntired of looking it up in the code, so I wrote the patch below. I don't\nknow if it is too crazy to be included in mainline git (it was discussed\na long time ago, but I think the general response was \"what would it be\ngood for?\").\n\n---\n cache.h     |    4 ++++\n refs.c      |    4 ++++\n sha1_file.c |    3 +--\n 3 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 30f1d62..4aa02ae 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -567,6 +567,10 @@ static inline unsigned int hexval(unsigned char c)\n #define MINIMUM_ABBREV 4\n #define DEFAULT_ABBREV 7\n \n+#define EMPTY_TREE_SHA1 \\\n+\t\"\\x4b\\x82\\x5d\\xc6\\x42\\xcb\\x6e\\xb9\\xa0\\x60\" \\\n+\t\"\\xe5\\x4b\\xf8\\xd6\\x92\\x88\\xfb\\xee\\x49\\x04\"\n+\n extern int get_sha1(const char *str, unsigned char *sha1);\n extern int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode);\n extern int get_sha1_hex(const char *hex, unsigned char *sha1);\ndiff --git a/refs.c b/refs.c\nindex 39a3b23..0acbcbc 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -427,6 +427,10 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *\n \t\t\t\t}\n \t\t\t\tlist = list->next;\n \t\t\t}\n+\t\t\tif (!strcmp(ref, \"EMPTY\")) {\n+\t\t\t\thashcpy(sha1, (unsigned char *)EMPTY_TREE_SHA1);\n+\t\t\t\treturn ref;\n+\t\t\t}\n \t\t\tif (reading || errno != ENOENT)\n \t\t\t\treturn NULL;\n \t\t\thashclr(sha1);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 2aff59b..38aad13 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1985,8 +1985,7 @@ static int cached_object_nr, cached_object_alloc;\n \n static struct cached_object empty_tree = {\n \t/* empty tree sha1: 4b825dc642cb6eb9a060e54bf8d69288fbee4904 */\n-\t\"\\x4b\\x82\\x5d\\xc6\\x42\\xcb\\x6e\\xb9\\xa0\\x60\"\n-\t\"\\xe5\\x4b\\xf8\\xd6\\x92\\x88\\xfb\\xee\\x49\\x04\",\n+\tEMPTY_TREE_SHA1,\n \tOBJ_TREE,\n \t\"\",\n \t0\n-- \n1.6.0.rc1.260.g4782\n"},{"id":"86497","messageId":"20080808132808.GA22674@atjola.homenet","threadId":"14889","inReplyTo":"489C40BC.8000008@sneakemail.com","subject":"Re: How to fix (and find) many git-* --check errors?","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2008-08-08T13:28:08Z","receivedAt":"2008-08-08T13:28:08Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2008.08.08 14:49:00 +0200, \"Peter Valdemar Mørch (Lists)\" wrote:\n> We have > 37000 white space \"errors\" in HEAD, mostly trailing  \n> whitespace, and I'm looking for a\n>\n> $ git diff --check | git??? --whitespace=fix\n>\n> command.\n>\n> Is there such a beast?\n>\n> I see that git-apply has a --whitespace=<action> option, but I don't  \n> seem to grock how to be able to use it for fixing my working directory.\n\nI'd probably do something like:\n\n# Create a commit with an empty tree\nrm .git/index\ngit commit -m tmp\n\nrm -r * (include dotfiles if required, ie. remove all tracked files)\n\ngit diff -R HEAD^ | git apply --index --whitespace=fix\ngit commit --amend -m \"Whitespace fixed up\"\n\nBut probably there's some smarter way than that.\n\nBjörn\n"},{"id":"86508","messageId":"489C5ED5.2060501@sneakemail.com","threadId":"14889","inReplyTo":"489C40BC.8000008@sneakemail.com","subject":"Re: How to fix (and find) many git-* --check errors?","fromName":"Peter Valdemar Mørch (Lists)","fromEmail":"4ux6as402@sneakemail.com","sentAt":"2008-08-08T14:57:25Z","receivedAt":"2008-08-08T14:57:25Z","isPatch":false,"sender":{"key":"4ux6as402@sneakemail.com","avatar":null},"body":"Thanks to hints from both Jeff King and Björn Stenbrink I got it \nworking. Here is my script, if anybody is interested.\n\nIt handles both fixing whitespace in current workspace diffs:\n\n$ git-fix-whitespace file\n\n(requires existing diffs)\n\nand fixing all whitespace problems in a file:\n\n$ git-fix-whitespace -f file\n\n(asserts no existing diffs)\n\nNow all I need to do is grock how to fix stuff already in the index, but \nI'll leave that for another day...\n\nPeter\n\n-----------------\n#!/bin/bash\n\n# Take a -f option to fix all whitespace problems in entire files\n# completely. Otherwise only fix current diffs.\n\n# Option handling\nwhile getopts fh? o\ndo\t\n     case \"$o\" in\n\tf)\tfixEntireFile=1;;\n\t[h?])\techo >&2 \"Usage: $0 [-f] file ...\"\n\t\techo >&2 \"-f: Fix the entire file\"\n\t\techo >&2 \"    Otherwise only fix current diffs\"\n\t\texit 1;;\n     esac\ndone\n\nshift $(($OPTIND-1))\n\n# A constant for a rev that is empty\nEMPTY_TREE_SHA1=4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\n# Check to see we're on a clean HEAD just to be sure.\n# (Not sure this is necessary, but just in case.)\ngit --no-pager diff --exit-code HEAD -- \"$@\"  > /dev/null\nif [ $? = 0 ] ; then\n\t# There is no current diff\n\tif [ \"$fixEntireFile\" != \"\" ] ; then\n\t\t# Good, there is no diff, and we've been asked to fix\n\t\t# the entire file\n\n\t\t# Remove all files - the -f for rm is just needed if\n\t\t# $@ happens to contain only untracked files\n\t\tgit-ls-tree -z  -r --name-status HEAD \"$@\"  | \\\n\t\t\txargs --null rm -f\n\n\t\t# Re-create the files - but with whitespace fixed\n\t\tgit diff $EMPTY_TREE_SHA1 HEAD -- \"$@\" | \\\n\t\t\tgit-apply --whitespace=fix\n\telse\n\t\techo >&2 '*Error*: there no diff with HEAD'\n\t\texit 1\n\tfi\nelse\n\t# There is a current diff\n\tif [ \"$fixEntireFile\" = \"\" ] ; then\n\t\t# Good, there is a current diff, that we need to fix\n\t\tTEMP_FILE=$(tempfile)\n\t\tgit diff -- \"$@\" > $TEMP_FILE\n\t\tgit checkout HEAD -- \"$@\"\n\t\tgit apply --whitespace=fix $TEMP_FILE\n\t\trm $TEMP_FILE\n\telse\n\t\techo >&2 '*Error*: there is diff with HEAD'\n\t\texit 1\n\tfi\nfi\n"},{"id":"86539","messageId":"7viqubcnop.fsf@gitster.siamese.dyndns.org","threadId":"14889","inReplyTo":"489C40BC.8000008@sneakemail.com","subject":"Re: How to fix (and find) many git-* --check errors?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-08T19:27:18Z","receivedAt":"2008-08-08T19:27:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Peter Valdemar Mørch (Lists)\"  <4ux6as402@sneakemail.com> writes:\n\n> We have > 37000 white space \"errors\" in HEAD, mostly trailing\n> whitespace, and I'm looking for a\n>\n> $ git diff --check | git??? --whitespace=fix\n>\n> command.\n\nStarting from a clean checkout, you could do something like this:\n\n\t$ git reset --hard\n        $ rm .git/index\n        $ git diff --binary -R HEAD >P.diff\n        $ git apply --whitespace=fix --cached <P.diff\n\t$ git commit -m \"Fixed all whitespace gotchas\"\n\nP.diff contains essentially everything, and you are recreating everything\nfrom that patch.\n"},{"id":"86579","messageId":"489D473B.3090406@sneakemail.com","threadId":"14889","inReplyTo":"7viqubcnop.fsf@gitster.siamese.dyndns.org","subject":"Re: How to fix (and find) many git-* --check errors?","fromName":"Peter Valdemar Mørch (Lists)","fromEmail":"4ux6as402@sneakemail.com","sentAt":"2008-08-09T07:28:59Z","receivedAt":"2008-08-09T07:28:59Z","isPatch":false,"sender":{"key":"4ux6as402@sneakemail.com","avatar":null},"body":"Junio C Hamano gitster-at-pobox.com |Lists| wrote:\n> Starting from a clean checkout, you could do something like this:\n> \n> \t$ git reset --hard\n>         $ rm .git/index\n>         $ git diff --binary -R HEAD >P.diff\n>         $ git apply --whitespace=fix --cached <P.diff\n> \t$ git commit -m \"Fixed all whitespace gotchas\"\n> \n> P.diff contains essentially everything, and you are recreating everything\n> from that patch.\n\nThanks for taking the time to answer my many mails and questions. It \nreally is helpful to me.\n\nRambling on:\n\nScary with the \"rm .git/index\"! It bascially creates an empty index it \nseems... That was news to me. As a newbie I try not to meddle too much \nin .git/ ...\n\nI tried the above on git.git, and it gave:\nwarning: 485 lines applied after fixing whitespace errors.\n\nI would suggest finishing the above with:\n$ git checkout HEAD\notherwise, the working dir is stuck at the old unfixed state.\n\nBut like I posted earlier, I have another solution that works on \nselected files. With git, there is always more than one way to do \nthings, it seems...\n\nPeter\n-- \nPeter Valdemar Mørch\nhttp://www.morch.com\n"}]}