{"thread":{"id":"2646","subject":"index manipulation -- how?","startedAt":"2005-11-22T05:03:37Z","lastAt":"2005-11-22T07:35:38Z","messageCount":7,"participants":["Luben Tuikov","Junio C Hamano","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"12512","messageId":"20051122050337.46450.qmail@web31808.mail.mud.yahoo.com","threadId":"2646","inReplyTo":null,"subject":"index manipulation -- how?","fromName":"Luben Tuikov","fromEmail":"ltuikov@yahoo.com","sentAt":"2005-11-22T05:03:37Z","receivedAt":"2005-11-22T05:03:37Z","isPatch":false,"sender":{"key":"ltuikov@yahoo.com","avatar":null},"body":"I've a question:\n\nSuppose I've updated the index and there is\nseveral updates pending in it: several new\nfiles, and several updates, etc.\n\nThat is a sequence of:\ngit-update-index [options] <file>\n...\n\nMy question is:\nHow do I reverse a _single_ \"git-update-index\" operation?\nBe it --add or just an update.\n\nThanks,\n    Luben\n"},{"id":"12515","messageId":"Pine.LNX.4.64.0511212113080.13959@g5.osdl.org","threadId":"2646","inReplyTo":"20051122050337.46450.qmail@web31808.mail.mud.yahoo.com","subject":"Re: index manipulation -- how?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-11-22T05:23:45Z","receivedAt":"2005-11-22T05:23:45Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 21 Nov 2005, Luben Tuikov wrote:\n> \n> How do I reverse a _single_ \"git-update-index\" operation?\n> Be it --add or just an update.\n\nAn \"add\" is easy enough to undo: just do a\n\n\tgit-update-index --force-remove filename\n\nwhich will remove the entry from the index even if the file on your \nfilesystem still remains (so you can \"git add\" it later when you do want \nto commit it).\n\nFor a file that you had in your old index, but you've updated (either mode \nor SHA1), you need to figure out what the old mode/sha1 was. USUALLY this \nwould be just the state that you still have in your HEAD tree, but if \nyou want to go back to something else, you'd need to figure out what that \nwas.\n\nIf it's the \"last commit\" state (ie just your HEAD state), then do\n\n\tgit-ls-tree HEAD filename\n\nwhich will show you the info, and then you do\n\n\tgit-update-index --cacheinfo <mode> <sha1> filename\n\nfrom that state.\n\nYou could obviously script something like \"git-downdate-index\":\n\n\t#!/bin/sh\n\tfilename=\"$1\"\n\ttree_info=$(git-ls-tree HEAD -- \"$filename\")\n\tif [ -z \"$tree_info\" ]; then\n\t\tgit-update-index --force-remove -- \"$filename\"\n\telse\n\t\techo \"$tree_info\" | while read mode type sha1 name; do\n\t\t\tgit-update-index --cacheinfo \"$mode\" \"$sha1\" \"$filename\"\n\t\tdone\n\tfi\n\nbut the above is totally untested, and \"git-downdate-index\" is a really \nsucky name too, so you'd need to rename it and test whether it does what \nyou want.\n\nHmm?\n\n\t\tLinus\n"},{"id":"12514","messageId":"7v8xvhi7bi.fsf@assigned-by-dhcp.cox.net","threadId":"2646","inReplyTo":"20051122050337.46450.qmail@web31808.mail.mud.yahoo.com","subject":"Re: index manipulation -- how?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-22T05:24:01Z","receivedAt":"2005-11-22T05:24:01Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Luben Tuikov <ltuikov@yahoo.com> writes:\n\n> How do I reverse a _single_ \"git-update-index\" operation?\n> Be it --add or just an update.\n\nReverting working tree files are \"git checkout HEAD the-file\"\n(both index and working tree file from the head commit) or \"git\ncheckout -- the-file\" (working tree file from the index), but I\ndo not think there is a prepackaged way to revert only a single\nindex path offhand.\n\n        git-ls-tree HEAD the-file |\n        sed -e 's/^\\([0-7]*\\) [^ ]* \\(.*\\)/\\1 \\2/' |\n        git-update-index --index-info\n\nshould work.\n\nI think changing update-index --index-info so that you can lose\nthe sed in between without breaking its other usage (it reads\nfrom git-apply --index-info, which does not say \" blob \" which\nis what the sed is stripping out) is a worthwhile thing to do.\n"},{"id":"12518","messageId":"7v3blpi6r7.fsf@assigned-by-dhcp.cox.net","threadId":"2646","inReplyTo":"7v8xvhi7bi.fsf@assigned-by-dhcp.cox.net","subject":"Re: index manipulation -- how?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-22T05:36:12Z","receivedAt":"2005-11-22T05:36:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> Luben Tuikov <ltuikov@yahoo.com> writes:\n>\n>> How do I reverse a _single_ \"git-update-index\" operation?\n>> Be it --add or just an update.\n>\n> Reverting working tree files are \"git checkout HEAD the-file\"\n> (both index and working tree file from the head commit) or \"git\n> checkout -- the-file\" (working tree file from the index), but I\n> do not think there is a prepackaged way to revert only a single\n> index path offhand.\n>\n>         git-ls-tree HEAD the-file |\n>         sed -e 's/^\\([0-7]*\\) [^ ]* \\(.*\\)/\\1 \\2/' |\n>         git-update-index --index-info\n>\n> should work.\n>\n> I think changing update-index --index-info so that you can lose\n> the sed in between without breaking its other usage (it reads\n> from git-apply --index-info, which does not say \" blob \" which\n> is what the sed is stripping out) is a worthwhile thing to do.\n\nAnd here is the patch to let you say:\n\n\tgit-ls-tree HEAD the-file | git-update-index --index-info\n\n\n---\n\ndiff --git a/update-index.c b/update-index.c\nindex 5bbc3de..11b7f6a 100644\n--- a/update-index.c\n+++ b/update-index.c\n@@ -338,7 +338,7 @@ static void read_index_info(int line_ter\n \tstruct strbuf buf;\n \tstrbuf_init(&buf);\n \twhile (1) {\n-\t\tchar *ptr;\n+\t\tchar *ptr, *tab;\n \t\tchar *path_name;\n \t\tunsigned char sha1[20];\n \t\tunsigned int mode;\n@@ -348,12 +348,15 @@ static void read_index_info(int line_ter\n \t\t\tbreak;\n \n \t\tmode = strtoul(buf.buf, &ptr, 8);\n-\t\tif (ptr == buf.buf || *ptr != ' ' ||\n-\t\t    get_sha1_hex(ptr + 1, sha1) ||\n-\t\t    ptr[41] != '\\t')\n+\t\tif (ptr == buf.buf || *ptr != ' ')\n \t\t\tgoto bad_line;\n \n-\t\tptr += 42;\n+\t\ttab = strchr(ptr, '\\t');\n+\t\tif (!tab || tab - ptr < 41)\n+\t\t\tgoto bad_line;\n+\t\tif (get_sha1_hex(tab - 40, sha1) || tab[-41] != ' ')\n+\t\t\tgoto bad_line;\n+\t\tptr = tab + 1;\n \n \t\tif (line_termination && ptr[0] == '\"')\n \t\t\tpath_name = unquote_c_style(ptr, NULL);\n"},{"id":"12520","messageId":"20051122062048.8891.qmail@web31805.mail.mud.yahoo.com","threadId":"2646","inReplyTo":"7v3blpi6r7.fsf@assigned-by-dhcp.cox.net","subject":"Re: index manipulation -- how?","fromName":"Luben Tuikov","fromEmail":"ltuikov@yahoo.com","sentAt":"2005-11-22T06:20:47Z","receivedAt":"2005-11-22T06:20:47Z","isPatch":false,"sender":{"key":"ltuikov@yahoo.com","avatar":null},"body":"--- Junio C Hamano <junkio@cox.net> wrote:\n\n> Junio C Hamano <junkio@cox.net> writes:\n> \n> > Luben Tuikov <ltuikov@yahoo.com> writes:\n> >\n> >> How do I reverse a _single_ \"git-update-index\" operation?\n> >> Be it --add or just an update.\n> >\n> > Reverting working tree files are \"git checkout HEAD the-file\"\n> > (both index and working tree file from the head commit) or \"git\n> > checkout -- the-file\" (working tree file from the index), but I\n> > do not think there is a prepackaged way to revert only a single\n> > index path offhand.\n> >\n> >         git-ls-tree HEAD the-file |\n> >         sed -e 's/^\\([0-7]*\\) [^ ]* \\(.*\\)/\\1 \\2/' |\n> >         git-update-index --index-info\n\nOk.\n(There is a very similar construct in git-checkout.sh.\nSo if you apply the patch below, please make sure\ngit-checkout.sh doesn't break.)\n\nQuestion: so in effect, more generally:\n  git checkout <tree-ish> <file>\n\nwould do the right thing: update index and the working\ntree as the file <file> looked as it was at <tree-ish>?\n\nIs that correct?  Can someone confirm/deny?\n\n   Luben\nP.S. So both methods as mentioned by Linus and Junio\ndo what I asked about.\n\n> >\n> > should work.\n> >\n> > I think changing update-index --index-info so that you can lose\n> > the sed in between without breaking its other usage (it reads\n> > from git-apply --index-info, which does not say \" blob \" which\n> > is what the sed is stripping out) is a worthwhile thing to do.\n> \n> And here is the patch to let you say:\n> \n> \tgit-ls-tree HEAD the-file | git-update-index --index-info\n> \n> \n> ---\n> \n> diff --git a/update-index.c b/update-index.c\n> index 5bbc3de..11b7f6a 100644\n> --- a/update-index.c\n> +++ b/update-index.c\n> @@ -338,7 +338,7 @@ static void read_index_info(int line_ter\n>  \tstruct strbuf buf;\n>  \tstrbuf_init(&buf);\n>  \twhile (1) {\n> -\t\tchar *ptr;\n> +\t\tchar *ptr, *tab;\n>  \t\tchar *path_name;\n>  \t\tunsigned char sha1[20];\n>  \t\tunsigned int mode;\n> @@ -348,12 +348,15 @@ static void read_index_info(int line_ter\n>  \t\t\tbreak;\n>  \n>  \t\tmode = strtoul(buf.buf, &ptr, 8);\n> -\t\tif (ptr == buf.buf || *ptr != ' ' ||\n> -\t\t    get_sha1_hex(ptr + 1, sha1) ||\n> -\t\t    ptr[41] != '\\t')\n> +\t\tif (ptr == buf.buf || *ptr != ' ')\n>  \t\t\tgoto bad_line;\n>  \n> -\t\tptr += 42;\n> +\t\ttab = strchr(ptr, '\\t');\n> +\t\tif (!tab || tab - ptr < 41)\n> +\t\t\tgoto bad_line;\n> +\t\tif (get_sha1_hex(tab - 40, sha1) || tab[-41] != ' ')\n> +\t\t\tgoto bad_line;\n> +\t\tptr = tab + 1;\n>  \n>  \t\tif (line_termination && ptr[0] == '\"')\n>  \t\t\tpath_name = unquote_c_style(ptr, NULL);\n> \n> \n> -\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> \n"},{"id":"12522","messageId":"7vbr0dgo1f.fsf@assigned-by-dhcp.cox.net","threadId":"2646","inReplyTo":"20051122062048.8891.qmail@web31805.mail.mud.yahoo.com","subject":"Re: index manipulation -- how?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-22T07:05:48Z","receivedAt":"2005-11-22T07:05:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Luben Tuikov <ltuikov@yahoo.com> writes:\n\n> (There is a very similar construct in git-checkout.sh.\n> So if you apply the patch below, please make sure\n> git-checkout.sh doesn't break.)\n\nThanks.\n\n> Question: so in effect, more generally:\n>   git checkout <tree-ish> <file>\n>\n> would do the right thing: update index and the working\n> tree as the file <file> looked as it was at <tree-ish>?\n\nYes that is correct.  Also by omitting <tree-ish> you can\ncheckout from the index.\n\nI thought what you originally wanted to do was revert only index\nwithout losing your changes from the working tree, so just to\nmake sure, the above does _not_ do it --- the named file in the\nworking tree is also reverted to the one from <tree-ish>.\n"},{"id":"12523","messageId":"20051122073538.4708.qmail@web31806.mail.mud.yahoo.com","threadId":"2646","inReplyTo":"7vbr0dgo1f.fsf@assigned-by-dhcp.cox.net","subject":"Re: index manipulation -- how?","fromName":"Luben Tuikov","fromEmail":"ltuikov@yahoo.com","sentAt":"2005-11-22T07:35:38Z","receivedAt":"2005-11-22T07:35:38Z","isPatch":false,"sender":{"key":"ltuikov@yahoo.com","avatar":null},"body":"--- Junio C Hamano <junkio@cox.net> wrote:\n> \n> I thought what you originally wanted to do was revert only index\n> without losing your changes from the working tree, so just to\n> make sure, the above does _not_ do it --- the named file in the\n> working tree is also reverted to the one from <tree-ish>.\n\nExactly what I want.\n\nThanks,\n   Luben\nP.S. I figured this one out in three stages:\nSince checked out files are in rw- mode, but unchecked\nfiles simply do not exist, first I want to \"revert\"\na changed file in the working tree -- this one is easy.\nThen the second stage is if also the index is updated\n(but no commit), and the last stage is if also\nthere is a commit, for which I think I know what to use.\n"}]}