{"thread":{"id":"28990","subject":"Bug report - local (and git ignored) file silently removed after checkout","startedAt":"2011-11-20T13:42:36Z","lastAt":"2011-11-29T18:17:30Z","messageCount":23,"participants":["Bertrand BENOIT","Junio C Hamano","Taylor Hedberg","Johannes Sixt","Philip Oakley","Nguyen Thai Ngoc Duy","Nguyễn Thái Ngọc Duy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"179764","messageId":"CAPRVejcpAZrLWCeHTZJr9Uk6_z6hTPQLLd6pCOKteYnRGMQ5ig@mail.gmail.com","threadId":"28990","inReplyTo":null,"subject":"Bug report - local (and git ignored) file silently removed after checkout","fromName":"Bertrand BENOIT","fromEmail":"projettwk@users.sourceforge.net","sentAt":"2011-11-20T13:42:36Z","receivedAt":"2011-11-20T13:42:36Z","isPatch":false,"sender":{"key":"projettwk@users.sourceforge.net","avatar":null},"body":"Hi,\n\nIn a (special ?) situation, I've lost a local (and git ignored) file\nsilently, and I've failed to get it back.\n\nContext:\n  - in previous version of my project, the TODO file was versioned\n  - in current development version, this file is NO more versioned AND\nit is ignored by a gitignore rule, but still at the same place for\nbetter ease of access -> such a way, this file has been locally\nupdated several times\n  - during worflow process, I've finally performed a checkout on a\nprevious version (in which the TODO file was versioned) -> after that\nthe file has been silently updated with the old version\n  - after modification, I've performed back a checkout on the current\nversion and this time my TODO file has been fully and silently removed\n\nQuestions:\n  - is it a behavior regarded as normal ?\n  - is there any way to get back the TODO file, in LOCAL version it\nwas before the first checkout ?\n  - in any case, is there any way to be warned (and to make the\ncheckout fail) of such situation (local ignored file being overwritten\nwith 'older' not-ignored version) ?\n\nThx,\nBest regards,\nTWK\n"},{"id":"179766","messageId":"7vehx2ijf8.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"CAPRVejcpAZrLWCeHTZJr9Uk6_z6hTPQLLd6pCOKteYnRGMQ5ig@mail.gmail.com","subject":"Re: Bug report - local (and git ignored) file silently removed after checkout","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-20T21:16:27Z","receivedAt":"2011-11-20T21:16:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Bertrand BENOIT <projettwk@users.sourceforge.net> writes:\n\n> Context:\n>   - in previous version of my project, the TODO file was versioned\n>   - in current development version, this file is NO more versioned AND\n> it is ignored by a gitignore rule,...\n\nWhat you observed is expected with all the versions of Git since the\ngitignore mechanism was introduced. The ignored files are \"not tracked,\nare cruft that can be removed to make room if it is necessary for checking\nout a tracked version, and would not want to track (e.g. build artifacts\nlike '*.o')\" (I am not saying that it is the most sane semantics, I am\njust stating the fact).\n\nWe do not have \"not tracked, but precious (e.g. your TODO)\" category; from\ntime to time we have discussed possibilities of adding such to enrich the\ncategorization, but nobody stepped up to actually do the work of designing\nlet alone coding such a beast.\n"},{"id":"179768","messageId":"20111120221930.GF14902@foodlogiq3-xp-d620.thebe.ath.cx","threadId":"28990","inReplyTo":"7vehx2ijf8.fsf@alter.siamese.dyndns.org","subject":"Re: Bug report - local (and git ignored) file silently removed after checkout","fromName":"Taylor Hedberg","fromEmail":"tmhedberg@gmail.com","sentAt":"2011-11-20T22:19:30Z","receivedAt":"2011-11-20T22:19:30Z","isPatch":false,"sender":{"key":"tmhedberg@gmail.com","avatar":"https://gravatar.com/avatar/d046da5ea94a7957169aef0fe122771a1f8d9387d39bc68fcfb1332978e11a6c?d=mp&s=160"},"body":"Junio C Hamano, Sun 2011-11-20 @ 13:16:27-0800:\n> We do not have \"not tracked, but precious (e.g. your TODO)\" category;\n> from time to time we have discussed possibilities of adding such to\n> enrich the categorization, but nobody stepped up to actually do the\n> work of designing let alone coding such a beast.\n\nIf I'm not mistaken, files ignored by .git/info/exclude rather than\n.gitignore do exhibit this behavior. That is, Git will refuse a checkout\nwith an error message if it would overwrite a path listed in that file.\n\nI don't know if that's actually intended behavior, but I've noticed it\nbefore and made use of it.\n"},{"id":"179771","messageId":"7vzkfqgn91.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"20111120221930.GF14902@foodlogiq3-xp-d620.thebe.ath.cx","subject":"Re: Bug report - local (and git ignored) file silently removed after checkout","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-21T03:36:42Z","receivedAt":"2011-11-21T03:36:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Taylor Hedberg <tmhedberg@gmail.com> writes:\n\n> Junio C Hamano, Sun 2011-11-20 @ 13:16:27-0800:\n>> We do not have \"not tracked, but precious (e.g. your TODO)\" category;\n>> from time to time we have discussed possibilities of adding such to\n>> enrich the categorization, but nobody stepped up to actually do the\n>> work of designing let alone coding such a beast.\n>\n> If I'm not mistaken, files ignored by .git/info/exclude rather than\n> .gitignore do exhibit this behavior.\n\nAs far as I am aware, info/exclude should work exactly the same as having\na .gitignore file at the root level of the working tree. Can you show a\nminimum reproduction recipe in a form of a patch to our test scripts in t/\nhierarchy?\n"},{"id":"179773","messageId":"4EC9FC81.3080306@viscovery.net","threadId":"28990","inReplyTo":"7vzkfqgn91.fsf@alter.siamese.dyndns.org","subject":"[PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2011-11-21T07:23:45Z","receivedAt":"2011-11-21T07:23:45Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"From: Johannes Sixt <j6t@kdbg.org>\n\nIt is an unintended accident that entries matched by .git/info/exclude are\nconsidered precious, but entries matched by .gitignore are not. That is,\n'git checkout' will overwrite untracked files matched by .gitignore, but\nrefuses to overwrite files matched by .git/info/exclude.\n\nIt is a lucky accident: it allows the distinction between \"untracked but\nprecious\" and \"untracked and garbage\". And it is a doubly lucky accident:\n.gitignore entries are meant for files like build products, which usually\naffect all consumers of a repository, whereas .git/info/exclude is\nintended for personal files, which frequently are precious (think of a\nTODO file).\n\nAdd a test that codifies the accident as wanted behavior.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\nAm 11/21/2011 4:36, schrieb Junio C Hamano:\n> As far as I am aware, info/exclude should work exactly the same as having\n> a .gitignore file at the root level of the working tree. Can you show a\n> minimum reproduction recipe in a form of a patch to our test scripts in t/\n> hierarchy?\n\nHere you are. As you can see from my commit message, IMO, this is\na very useful accident. Therefore, there is no 'test_expect_failure'\nin the test script :-)\n\n-- Hannes\n\n t/t2023-checkout-ignored.sh |   51 +++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 51 insertions(+), 0 deletions(-)\n create mode 100755 t/t2023-checkout-ignored.sh\n\ndiff --git a/t/t2023-checkout-ignored.sh b/t/t2023-checkout-ignored.sh\nnew file mode 100755\nindex 0000000..03a5a56\n--- /dev/null\n+++ b/t/t2023-checkout-ignored.sh\n@@ -0,0 +1,51 @@\n+#!/bin/sh\n+\n+test_description='checkout overwrites or preserves ignored files\n+\n+`git checkout` makes a distinction between files mentioned in\n+.gitignore and .git/info/exclude in that untracked files matched\n+by the latter are considered precious and are not overwritten.\n+'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\n+\techo excluded > excluded &&\n+\techo ignored > ignored &&\n+\tgit add . &&\n+\ttest_commit initial &&\n+\tgit checkout -b side &&\n+\tgit rm excluded &&\n+\tgit mv ignored .gitignore &&\n+\ttest_commit side &&\n+\techo excluded >> .git/info/exclude\n+'\n+\n+test_expect_success 'files are ignored' '\n+\n+\techo keep > excluded &&\n+\techo overwrite > ignored &&\n+\tlist=$(git ls-files --others --exclude-standard) &&\n+\ttest -z \"$list\"\n+'\n+\n+test_expect_success 'entries in .git/info/exclude are precious' '\n+\n+\ttest_must_fail git checkout master 2>errors &&\n+\ttest_i18ngrep \"would be overwritten\" errors &&\n+\tgrep \"\texcluded\" errors &&\n+\t! grep \"\tignored\" errors &&\n+\tgrep keep excluded &&\n+\tgrep overwrite ignored\n+'\n+\n+test_expect_success 'entries in .gitignore are not precious' '\n+\n+\trm -f excluded &&\n+\tgit checkout master &&\n+\tgrep excluded excluded &&\n+\tgrep ignored ignored\n+'\n+\n+test_done\n-- \n1.7.8.rc0.126.gd15506\n"},{"id":"179774","messageId":"00392567F0B045E38A429F95594C1BD2@PhilipOakley","threadId":"28990","inReplyTo":"4EC9FC81.3080306@viscovery.net","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2011-11-21T07:23:45Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Johannes Sixt\" <j.sixt@viscovery.net>\n> From: Johannes Sixt <j6t@kdbg.org>\n>\n> It is an unintended accident that entries matched by .git/info/exclude are\n> considered precious, but entries matched by .gitignore are not. That is,\n> 'git checkout' will overwrite untracked files matched by .gitignore, but\n> refuses to overwrite files matched by .git/info/exclude.\n>\n> It is a lucky accident: it allows the distinction between \"untracked but\n> precious\" and \"untracked and garbage\". And it is a doubly lucky accident:\n> .gitignore entries are meant for files like build products, which usually\n> affect all consumers of a repository, whereas .git/info/exclude is\n> intended for personal files, which frequently are precious (think of a\n> TODO file).\n>\n> Add a test that codifies the accident as wanted behavior.\n>\n> Signed-off-by: Johannes Sixt <j6t@kdbg.org>\n> ---\n> Am 11/21/2011 4:36, schrieb Junio C Hamano:\n>> As far as I am aware, info/exclude should work exactly the same as having\n>> a .gitignore file at the root level of the working tree. Can you show a\n>> minimum reproduction recipe in a form of a patch to our test scripts in \n>> t/\n>> hierarchy?\n>\n> Here you are. As you can see from my commit message, IMO, this is\n> a very useful accident. Therefore, there is no 'test_expect_failure'\n> in the test script :-)\n\nShouldn't there be some documentation changes to support this very useful \nfeature. By documenting the existing code functionality  we get the double \nbenefit of no code changes and we publish the existance of a desired bit of \nfunctionality.\nPhilip\n\n>\n> -- Hannes\n>\n> t/t2023-checkout-ignored.sh |   51 \n> +++++++++++++++++++++++++++++++++++++++++++\n> 1 files changed, 51 insertions(+), 0 deletions(-)\n> create mode 100755 t/t2023-checkout-ignored.sh\n>\n> diff --git a/t/t2023-checkout-ignored.sh b/t/t2023-checkout-ignored.sh\n> new file mode 100755\n> index 0000000..03a5a56\n> --- /dev/null\n> +++ b/t/t2023-checkout-ignored.sh\n> @@ -0,0 +1,51 @@\n> +#!/bin/sh\n> +\n> +test_description='checkout overwrites or preserves ignored files\n> +\n> +`git checkout` makes a distinction between files mentioned in\n> +.gitignore and .git/info/exclude in that untracked files matched\n> +by the latter are considered precious and are not overwritten.\n> +'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success setup '\n> +\n> + echo excluded > excluded &&\n> + echo ignored > ignored &&\n> + git add . &&\n> + test_commit initial &&\n> + git checkout -b side &&\n> + git rm excluded &&\n> + git mv ignored .gitignore &&\n> + test_commit side &&\n> + echo excluded >> .git/info/exclude\n> +'\n> +\n> +test_expect_success 'files are ignored' '\n> +\n> + echo keep > excluded &&\n> + echo overwrite > ignored &&\n> + list=$(git ls-files --others --exclude-standard) &&\n> + test -z \"$list\"\n> +'\n> +\n> +test_expect_success 'entries in .git/info/exclude are precious' '\n> +\n> + test_must_fail git checkout master 2>errors &&\n> + test_i18ngrep \"would be overwritten\" errors &&\n> + grep \" excluded\" errors &&\n> + ! grep \" ignored\" errors &&\n> + grep keep excluded &&\n> + grep overwrite ignored\n> +'\n> +\n> +test_expect_success 'entries in .gitignore are not precious' '\n> +\n> + rm -f excluded &&\n> + git checkout master &&\n> + grep excluded excluded &&\n> + grep ignored ignored\n> +'\n> +\n> +test_done\n> -- \n> 1.7.8.rc0.126.gd15506\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>\n> -----\n> No virus found in this message.\n> Checked by AVG - www.avg.com\n> Version: 2012.0.1872 / Virus Database: 2092/4628 - Release Date: 11/20/11\n> \n"},{"id":"179775","messageId":"7vsjlhhq33.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"4EC9FC81.3080306@viscovery.net","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-21T07:50:08Z","receivedAt":"2011-11-21T07:50:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> It is a lucky accident: it allows the distinction between \"untracked but\n> precious\" and \"untracked and garbage\". And it is a doubly lucky accident:\n> .gitignore entries are meant for files like build products, which usually\n> affect all consumers of a repository, whereas .git/info/exclude is\n> intended for personal files, which frequently are precious (think of a\n> TODO file).\n> ...\n> Here you are. As you can see from my commit message, IMO, this is\n> a very useful accident. Therefore, there is no 'test_expect_failure'\n> in the test script :-)\n\nHeh.\n\nIf this is a feature, we would like a patch to Documentation/gitignore.txt\nas well, I think.  Also I have a suspicion that this was an unintended\n\"regression\"; do you have a bisection?\n"},{"id":"179776","messageId":"7vobw5hpno.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"00392567F0B045E38A429F95594C1BD2@PhilipOakley","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-21T07:59:23Z","receivedAt":"2011-11-21T07:59:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Philip Oakley\" <philipoakley@iee.org> writes:\n\n> Shouldn't there be some documentation changes to support this very\n> useful feature.\n\nI do not agree it is \"useful\", if it is info/exclude only, which by design\nwould not propagate across repositories and histories.\n\nIf we were to support \"precious\" as a feature, we should do that properly\nwith a properly defined syntax (e.g. just like '!' prefix is \"no, this is\nnot 'ignored' entry\", use some prefix to say \"well, this is ignored in the\nsense that not to be tracked, but that does not mean this can be nuked\")\nthat can be in any exclude sources.\n\nExclude patterns in info/exclude should work just like ones in the in-tree\n.gitignore only at different precedence for uniformity and consistency, so\nthe behaviour J6t showed in the new test should be fixed.\n\nThe entries in info/exclude are at lower priority than the ones in in-tree\n.gitignore files, which probably was a design mistake, but that is a\nseparate issue.\n"},{"id":"179777","messageId":"20111121081701.GA7985@do","threadId":"28990","inReplyTo":"4EC9FC81.3080306@viscovery.net","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-21T08:17:01Z","receivedAt":"2011-11-21T08:17:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Nov 21, 2011 at 08:23:45AM +0100, Johannes Sixt wrote:\n> From: Johannes Sixt <j6t@kdbg.org>\n> \n> It is an unintended accident that entries matched by .git/info/exclude are\n> considered precious, but entries matched by .gitignore are not. That is,\n> 'git checkout' will overwrite untracked files matched by .gitignore, but\n> refuses to overwrite files matched by .git/info/exclude.\n> \n> It is a lucky accident: it allows the distinction between \"untracked but\n> precious\" and \"untracked and garbage\". And it is a doubly lucky accident:\n> .gitignore entries are meant for files like build products, which usually\n> affect all consumers of a repository, whereas .git/info/exclude is\n> intended for personal files, which frequently are precious (think of a\n> TODO file).\n> \n> Add a test that codifies the accident as wanted behavior.\n\nIf you want to keep this accident (which is a bug to me), you may want\nto add the reason: callers to unpack_trees() are supposed to also\nsetup exclude rules in .git/info/exclude before calling\nunpack_trees(), which they don't.\n\nSo .git/info/exclude is entirely dismissed. This patch makes t2023.3\nfail. I haven't dug into history to see if this is on purpose though.\n\n-- 8< --\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 2a80772..c2fc2ba 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -412,6 +412,8 @@ static int merge_working_tree(struct checkout_opts *opts,\n \t\ttopts.dir = xcalloc(1, sizeof(*topts.dir));\n \t\ttopts.dir->flags |= DIR_SHOW_IGNORED;\n \t\ttopts.dir->exclude_per_dir = \".gitignore\";\n+\t\tif (!access(git_path(\"info/exclude\"), R_OK))\n+\t\t\tadd_excludes_from_file(topts.dir, git_path(\"info/exclude\"));\n \t\ttree = parse_tree_indirect(old->commit ?\n \t\t\t\t\t   old->commit->object.sha1 :\n \t\t\t\t\t   EMPTY_TREE_SHA1_BIN);\n-- 8< --\n--\nDuy\n"},{"id":"179778","messageId":"CACsJy8AgDKYhyJ2CD0Y7trGrT63bUuYAS0DadD9khyqEYpguew@mail.gmail.com","threadId":"28990","inReplyTo":"7vsjlhhq33.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-21T08:52:50Z","receivedAt":"2011-11-21T08:52:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Nov 21, 2011 at 2:50 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> If this is a feature, we would like a patch to Documentation/gitignore.txt\n> as well, I think.  Also I have a suspicion that this was an unintended\n> \"regression\"; do you have a bisection?\n\nIt dated back to f8a9d42 (read-tree: further loosen \"working file will\nbe lost\" check. - 2006-12-04) when you introduced\n--exclude-per-directory to read-tree, but not --exclude-from to\nexplicitly add .git/info/exclude. \"read tree --exclude-per-directory\"\nis used in git-checkout.sh and the same logic is carried over to\nbuiltin-checkout.c until today.\n\nI guess it's time to add \"read-tree --exclude-from\". Not sure what to\ndo with git-checkout though. We may add an option to checkout to skip\neither .git/info/exclude or .gitignore, or both.\n-- \nDuy\n"},{"id":"179786","messageId":"7vk46th5bz.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"20111121081701.GA7985@do","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-21T15:18:24Z","receivedAt":"2011-11-21T15:18:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> If you want to keep this accident (which is a bug to me), you may want\n> to add the reason: callers to unpack_trees() are supposed to also\n> setup exclude rules in .git/info/exclude before calling\n> unpack_trees(), which they don't.\n>\n> So .git/info/exclude is entirely dismissed.\n\nOhh, thanks for this and also for digging this through in your other\nmessage.\n\nI think it is the right thing to do to make sure .gitignore and\ninfo/exclude behave the same way regardless of the original issue in this\ntopic.\n\nIn the medium term, I think one reasonable way forward solving the \"TODO\nthat used to be tracked but now untracked and ignored\" issue is to\nintroduce \"info/exclude-override\" that comes between command line and\nin-tree patterns. The info/exclude file is designed as the fallback\ndefinition to be used when all other sources are too lax, and comes near\nthe precedence stack; the \"TODO\" situation however calls for an override\nthat is stronger than the in-tree patterns.\n\nIn the longer term, we should carefully determine if we need \"precious\" in\nthe first place. The last time this was brought up there were people who\nargued they are OK with having to remove the ignored file by hand when\nchecking out another branch (i.e. we switch the semantics of \"ignored\" so\nthat they are \"not tracked but all precious\").\n\nI think it matters in two cases.\n\n (1) If you change an untracked \"cruft\" file on branch A into a directory\n     with tracked files in it on another branch B. If you are on branch A,\n     have that \"cruft\" file (perhaps it is a build product after running\n     \"make\"), and try to checkout branch B, such an updated \"git checkout\"\n     will start erroring out telling you that \"cruft\" will be lost.\n\n (2) If you have a directory on branch A, underneath of which there are\n     untracked \"cruft\" files (e.g. think \"build/\" directory that is full\n     of \"*.o\" files and \".gitignore\" to mark object files as ignored but\n     is otherwise empty), and another branch B that has the same path as a\n     file. If you are on branch A, have \"cruft\" files in that directory,\n     and try to checkout branch B, such an updated \"git checkout\" will\n     start erroring out telling you that \"cruft\" will be lost.\n\nIf people are OK with such a behaviour, we can do without \"precious\".\n\nOtherwise we would need to update excluded() in dir.c to return tristate\n(ignored, precious or unspecified) instead of the current boolean (ignored\nor unspecified), examine and decide for each caller what they want to do\nto \"precious\" files.\n"},{"id":"179789","messageId":"CAPRVejf71ke-RcbQQfiPUFAdzyBMAGCKnmBuaF2mOneuBF-TYQ@mail.gmail.com","threadId":"28990","inReplyTo":"7vk46th5bz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Bertrand BENOIT","fromEmail":"projettwk@users.sourceforge.net","sentAt":"2011-11-21T15:44:51Z","receivedAt":"2011-11-21T15:44:51Z","isPatch":true,"sender":{"key":"projettwk@users.sourceforge.net","avatar":null},"body":"2011/11/21 Junio C Hamano <gitster@pobox.com>:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> If you want to keep this accident (which is a bug to me), you may want\n>> to add the reason: callers to unpack_trees() are supposed to also\n>> setup exclude rules in .git/info/exclude before calling\n>> unpack_trees(), which they don't.\n>>\n>> So .git/info/exclude is entirely dismissed.\n>\n> Ohh, thanks for this and also for digging this through in your other\n> message.\n>\n> I think it is the right thing to do to make sure .gitignore and\n> info/exclude behave the same way regardless of the original issue in this\n> topic.\n>\n> In the medium term, I think one reasonable way forward solving the \"TODO\n> that used to be tracked but now untracked and ignored\" issue is to\n> introduce \"info/exclude-override\" that comes between command line and\n> in-tree patterns. The info/exclude file is designed as the fallback\n> definition to be used when all other sources are too lax, and comes near\n> the precedence stack; the \"TODO\" situation however calls for an override\n> that is stronger than the in-tree patterns.\n>\n> In the longer term, we should carefully determine if we need \"precious\" in\n> the first place. The last time this was brought up there were people who\n> argued they are OK with having to remove the ignored file by hand when\n> checking out another branch (i.e. we switch the semantics of \"ignored\" so\n> that they are \"not tracked but all precious\").\n>\n> I think it matters in two cases.\n>\n>  (1) If you change an untracked \"cruft\" file on branch A into a directory\n>     with tracked files in it on another branch B. If you are on branch A,\n>     have that \"cruft\" file (perhaps it is a build product after running\n>     \"make\"), and try to checkout branch B, such an updated \"git checkout\"\n>     will start erroring out telling you that \"cruft\" will be lost.\n>\n>  (2) If you have a directory on branch A, underneath of which there are\n>     untracked \"cruft\" files (e.g. think \"build/\" directory that is full\n>     of \"*.o\" files and \".gitignore\" to mark object files as ignored but\n>     is otherwise empty), and another branch B that has the same path as a\n>     file. If you are on branch A, have \"cruft\" files in that directory,\n>     and try to checkout branch B, such an updated \"git checkout\" will\n>     start erroring out telling you that \"cruft\" will be lost.\n>\n> If people are OK with such a behaviour, we can do without \"precious\".\n>\n> Otherwise we would need to update excluded() in dir.c to return tristate\n> (ignored, precious or unspecified) instead of the current boolean (ignored\n> or unspecified), examine and decide for each caller what they want to do\n> to \"precious\" files.\n\nIMO, as user, I think that erroring out telling you that 'cruft' will\nbe lost, is enough to avoid data loss.\nHowever, in addition the tristate system (with a dedicated syntax in\n.gitattributes and/or .gitignore files) would give more freedom,\nwithout having to move 'untracked but precious' files between each\nupdated 'git checkout'.\n"},{"id":"179792","messageId":"7vfwhhgzcb.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"CACsJy8AgDKYhyJ2CD0Y7trGrT63bUuYAS0DadD9khyqEYpguew@mail.gmail.com","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-21T17:27:48Z","receivedAt":"2011-11-21T17:27:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> It dated back to f8a9d42 (read-tree: further loosen \"working file will\n> be lost\" check. - 2006-12-04) when you introduced --exclude-per-directory\n> to read-tree, but not --exclude-from to explicitly add .git/info/exclude.\n\nThat one together with 1127148 (Loosen \"working file will be lost\" check\nin Porcelain-ish, 2006-12-04) complets the picture. Thanks for digging\nthis out.\n\n> I guess it's time to add \"read-tree --exclude-from\".\n\nPerhaps, also --exclude-standard to match?\n\n> We may add an option to checkout to skip\n> either .git/info/exclude or .gitignore, or both.\n\nI do not think we want to go that route, because it is not just \"checkout\"\nbut is an issue shared across users of unpack-trees machinery.\n\nWhen a merge result loses build/ directory and replaces it with a regular\nfile \"build\", with the current ignore semantics, build/*.o will go but if\nyou had an untracked and ignored build/TODO, the file will also go, for\nexample. If we want to have \"precious\", we should either make \"ignored\" to\nmean \"precious\", or introduce a \"precious\" as a new category\n(cf. $gmane/185746)\n"},{"id":"179876","messageId":"CACsJy8AM-NyCcoCO2ssdPEGKXT3ODcc4ObZTrjn8K+Tz61woTw@mail.gmail.com","threadId":"28990","inReplyTo":"7vfwhhgzcb.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-23T11:31:34Z","receivedAt":"2011-11-23T11:31:34Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Nov 22, 2011 at 12:27 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> It dated back to f8a9d42 (read-tree: further loosen \"working file will\n>> be lost\" check. - 2006-12-04) when you introduced --exclude-per-directory\n>> to read-tree, but not --exclude-from to explicitly add .git/info/exclude.\n>\n> That one together with 1127148 (Loosen \"working file will be lost\" check\n> in Porcelain-ish, 2006-12-04) complets the picture. Thanks for digging\n> this out.\n>\n>> I guess it's time to add \"read-tree --exclude-from\".\n>\n> Perhaps, also --exclude-standard to match?\n\nYep, will do.\n-- \nDuy\n"},{"id":"179879","messageId":"CACsJy8A7HVe8kLR5j9Ej0tJhpkxigCXRqpg9DvE9qJsfengi1Q@mail.gmail.com","threadId":"28990","inReplyTo":"7vk46th5bz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-23T11:40:34Z","receivedAt":"2011-11-23T11:40:34Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Nov 21, 2011 at 10:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> In the medium term, I think one reasonable way forward solving the \"TODO\n> that used to be tracked but now untracked and ignored\" issue is to\n> introduce \"info/exclude-override\" that comes between command line and\n> in-tree patterns. The info/exclude file is designed as the fallback\n> definition to be used when all other sources are too lax, and comes near\n> the precedence stack; the \"TODO\" situation however calls for an override\n> that is stronger than the in-tree patterns.\n\n\"info/precious\" might be a better name\n\n> In the longer term, we should carefully determine if we need \"precious\" in\n> the first place. The last time this was brought up there were people who\n> argued they are OK with having to remove the ignored file by hand when\n> checking out another branch (i.e. we switch the semantics of \"ignored\" so\n> that they are \"not tracked but all precious\").\n>\n> I think it matters in two cases.\n>\n>  (1) If you change an untracked \"cruft\" file on branch A into a directory\n>     with tracked files in it on another branch B. If you are on branch A,\n>     have that \"cruft\" file (perhaps it is a build product after running\n>     \"make\"), and try to checkout branch B, such an updated \"git checkout\"\n>     will start erroring out telling you that \"cruft\" will be lost.\n>\n>  (2) If you have a directory on branch A, underneath of which there are\n>     untracked \"cruft\" files (e.g. think \"build/\" directory that is full\n>     of \"*.o\" files and \".gitignore\" to mark object files as ignored but\n>     is otherwise empty), and another branch B that has the same path as a\n>     file. If you are on branch A, have \"cruft\" files in that directory,\n>     and try to checkout branch B, such an updated \"git checkout\" will\n>     start erroring out telling you that \"cruft\" will be lost.\n\nI think we should do this regardless precious being added or not.\n\n> If people are OK with such a behaviour, we can do without \"precious\".\n\nWhat about git-clean to remove ignored but not precious files?\n\n> Otherwise we would need to update excluded() in dir.c to return tristate\n> (ignored, precious or unspecified) instead of the current boolean (ignored\n> or unspecified), examine and decide for each caller what they want to do\n> to \"precious\" files.\n\nOr do excluded() twice, the first time to check for precious files,\nthe second for all ignored rules. Callers are changed anyway, but this\nway git-add for example will be untouched because it does not care\nabout precious stuff. Only unpack-trees and maybe git-clean are\nchanged.\n-- \nDuy\n"},{"id":"179892","messageId":"7vy5v6bvy4.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"CACsJy8A7HVe8kLR5j9Ej0tJhpkxigCXRqpg9DvE9qJsfengi1Q@mail.gmail.com","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-23T17:16:51Z","receivedAt":"2011-11-23T17:16:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> On Mon, Nov 21, 2011 at 10:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> In the medium term, I think one reasonable way forward solving the \"TODO\n>> that used to be tracked but now untracked and ignored\" issue is to\n>> introduce \"info/exclude-override\" that comes between command line and\n>> in-tree patterns. The info/exclude file is designed as the fallback\n>> definition to be used when all other sources are too lax, and comes near\n>> the precedence stack; the \"TODO\" situation however calls for an override\n>> that is stronger than the in-tree patterns.\n>\n> \"info/precious\" might be a better name\n\nThe above is only about the precedence order and is not about introducing\nthe new \"precious\" class at all.\n\n>> In the longer term, we should carefully determine if we need \"precious\" in\n>> the first place. The last time this was brought up there were people who\n>> argued they are OK with having to remove the ignored file by hand when\n>> checking out another branch (i.e. we switch the semantics of \"ignored\" so\n>> that they are \"not tracked but all precious\").\n>>\n>> I think it matters in two cases.\n>>\n>>  (1) If you change an untracked \"cruft\" file on branch A into a directory\n>>     with tracked files in it on another branch B. If you are on branch A,\n>>     have that \"cruft\" file (perhaps it is a build product after running\n>>     \"make\"), and try to checkout branch B, such an updated \"git checkout\"\n>>     will start erroring out telling you that \"cruft\" will be lost.\n>>\n>>  (2) If you have a directory on branch A, underneath of which there are\n>>     untracked \"cruft\" files (e.g. think \"build/\" directory that is full\n>>     of \"*.o\" files and \".gitignore\" to mark object files as ignored but\n>>     is otherwise empty), and another branch B that has the same path as a\n>>     file. If you are on branch A, have \"cruft\" files in that directory,\n>>     and try to checkout branch B, such an updated \"git checkout\" will\n>>     start erroring out telling you that \"cruft\" will be lost.\n>\n> I think we should do this regardless precious being added or not.\n\nBecause (see below)?\n\n>> If people are OK with such a behaviour, we can do without \"precious\".\n>\n> What about git-clean to remove ignored but not precious files?\n\n\"clean\" without -x is a way to remove untracked and not ignored files,\ni.e. remove \"test.c\", \"trash-patch\", \"notes\" that are not part of the\nsources but were crufts you hand generated during your development process\nthat you do not need, without removing build products such as \"main.o\". If\nwe switch the semantics of \"ignored\" from \"untracked and is expendable for\nthe purpose of checking out another conflicting branch\" to \"untracked but\nis not expendable\", it is clear that it should not remove them.\n\n\"clean -x\" is more subtle. It has been a way to say \"Remove cruft the\nusual way, and in addition, remove the expendable build products, just\nlike 'make clean' _should_ do, but I do not trust my Makefile\". If we\nintroduced \"precious\", it would be very clear what it should do---even\nwith \"-x\" precious files should be kept. But if we don't and just try to\nget away by changing the semantics of \"ignored\", they will still need to\nbe removed, so we won't really get the \"precious\".\n\nThe conclusion from this is that it is a mistake to change the semantics\nof \"ignored\" from the current \"untracked and expendable if needed\" if the\npurpose of that change is to avoid introducing the new \"precious\" class.\n\nI don't care too much about it, as I do not use \"git clean -x\" myself ;-)\nbut that wouldn't stop others from think about the issue and try to come\nup with a good solid design.\n\n> Or do excluded() twice, the first time to check for precious files,\n> the second for all ignored rules. Callers are changed anyway, but this\n> way git-add for example will be untouched because it does not care\n> about precious stuff. Only unpack-trees and maybe git-clean are\n> changed.\n\nI don't think we want to go there, as it will encourage different\ncodepaths doing different things without a good reason. Having to add\nignore source manually in different codepaths was the real cause of the\ninconsistency bug around info/exclude vs .gitignore we discussed earlier.\n"},{"id":"179924","messageId":"CACsJy8BYN-nu6a92dk-qpF5_jR_frKwg+DD1EThr2kMPGHV5kQ@mail.gmail.com","threadId":"28990","inReplyTo":"7vy5v6bvy4.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-24T01:35:48Z","receivedAt":"2011-11-24T01:35:48Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Nov 24, 2011 at 12:16 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> On Mon, Nov 21, 2011 at 10:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> In the medium term, I think one reasonable way forward solving the \"TODO\n>>> that used to be tracked but now untracked and ignored\" issue is to\n>>> introduce \"info/exclude-override\" that comes between command line and\n>>> in-tree patterns. The info/exclude file is designed as the fallback\n>>> definition to be used when all other sources are too lax, and comes near\n>>> the precedence stack; the \"TODO\" situation however calls for an override\n>>> that is stronger than the in-tree patterns.\n>>\n>> \"info/precious\" might be a better name\n>\n> The above is only about the precedence order and is not about introducing\n> the new \"precious\" class at all.\n\nThe way I see how info/exclude-override helps keep (ignored but)\nprecious files is it un-ignores files that are ignored by info/exclude\nand .gitignore. But if we go that way, then git-add will also\nun-ignore precious files, allowing users to add them in-tree by\nmistake.\n\n>>> In the longer term, we should carefully determine if we need \"precious\" in\n>>> the first place. The last time this was brought up there were people who\n>>> argued they are OK with having to remove the ignored file by hand when\n>>> checking out another branch (i.e. we switch the semantics of \"ignored\" so\n>>> that they are \"not tracked but all precious\").\n>>>\n>>> I think it matters in two cases.\n>>>\n>>>  (1) If you change an untracked \"cruft\" file on branch A into a directory\n>>>     with tracked files in it on another branch B. If you are on branch A,\n>>>     have that \"cruft\" file (perhaps it is a build product after running\n>>>     \"make\"), and try to checkout branch B, such an updated \"git checkout\"\n>>>     will start erroring out telling you that \"cruft\" will be lost.\n>>>\n>>>  (2) If you have a directory on branch A, underneath of which there are\n>>>     untracked \"cruft\" files (e.g. think \"build/\" directory that is full\n>>>     of \"*.o\" files and \".gitignore\" to mark object files as ignored but\n>>>     is otherwise empty), and another branch B that has the same path as a\n>>>     file. If you are on branch A, have \"cruft\" files in that directory,\n>>>     and try to checkout branch B, such an updated \"git checkout\" will\n>>>     start erroring out telling you that \"cruft\" will be lost.\n>>\n>> I think we should do this regardless precious being added or not.\n>\n> Because (see below)?\n\nBecause it may potentially lose user's changes. Assume file \"A\" is\ntracked and also ignored. Users may make some changes in A, then move\nHEAD away without touching worktree, now HEAD does not see \"A\" as\ntracked any more. If we switch to a branch that has A tracked, git may\noverride A and wipe our user changes in that file. In short, if a file\nis tracked (either in source or target in 2-way merge) then we ignore\nexcluded() result on that file.\n\n>>> If people are OK with such a behaviour, we can do without \"precious\".\n>>\n>> What about git-clean to remove ignored but not precious files?\n>\n(git clean without -x snipped because I was talking about -x)\n>\n> \"clean -x\" is more subtle. It has been a way to say \"Remove cruft the\n> usual way, and in addition, remove the expendable build products, just\n> like 'make clean' _should_ do, but I do not trust my Makefile\". If we\n> introduced \"precious\", it would be very clear what it should do---even\n> with \"-x\" precious files should be kept. But if we don't and just try to\n> get away by changing the semantics of \"ignored\", they will still need to\n> be removed, so we won't really get the \"precious\".\n>\n> The conclusion from this is that it is a mistake to change the semantics\n> of \"ignored\" from the current \"untracked and expendable if needed\" if the\n> purpose of that change is to avoid introducing the new \"precious\" class.\n>\n> I don't care too much about it, as I do not use \"git clean -x\" myself ;-)\n> but that wouldn't stop others from think about the issue and try to come\n> up with a good solid design.\n\nI don't use \"git clean -x\" myself either. This is just some input to\nthe discussion and true users are supposed to speak up. The point I\nwant to make is, if users really want the ability remove non-precious\nignored files, then we may need to add the new \"precious\" class that\n(and you seem to reach the same conclusion).\n-- \nDuy\n"},{"id":"179926","messageId":"7vlir69k0s.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"CACsJy8BYN-nu6a92dk-qpF5_jR_frKwg+DD1EThr2kMPGHV5kQ@mail.gmail.com","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-24T05:17:23Z","receivedAt":"2011-11-24T05:17:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> ...\n>>> I think we should do this regardless precious being added or not.\n>>\n>> Because (see below)?\n>\n> Because it may potentially lose user's changes. Assume file \"A\" is\n> tracked and also ignored. Users may make some changes in A, then move\n> HEAD away without touching worktree, now HEAD does not see \"A\" as\n> tracked any more.\n\nHuh? \"A\" is initially tracked and the user modifies it. Moving HEAD away\nhow?  \"git checkout\" would refuse to check out a branch that has different\ncontents at \"A\", or is missing \"A\". So how can \"now HEAD does not see 'A'\nas tracked any more\" happen?\n"},{"id":"179927","messageId":"CACsJy8Dj3MmVFZpPXB9pYKyKbp=jifFr64Ckv38Y1c-JbuVXHg@mail.gmail.com","threadId":"28990","inReplyTo":"7vlir69k0s.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-24T05:39:49Z","receivedAt":"2011-11-24T05:39:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Nov 24, 2011 at 12:17 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n>\n>> ...\n>>>> I think we should do this regardless precious being added or not.\n>>>\n>>> Because (see below)?\n>>\n>> Because it may potentially lose user's changes. Assume file \"A\" is\n>> tracked and also ignored. Users may make some changes in A, then move\n>> HEAD away without touching worktree, now HEAD does not see \"A\" as\n>> tracked any more.\n>\n> Huh? \"A\" is initially tracked and the user modifies it. Moving HEAD away\n> how?  \"git checkout\" would refuse to check out a branch that has different\n> contents at \"A\", or is missing \"A\". So how can \"now HEAD does not see 'A'\n> as tracked any more\" happen?\n\ngit reset <somewhere else>\n-- \nDuy\n"},{"id":"180013","messageId":"CACsJy8AXLBNSPmeEJjD1QX2zF1ic+S9kb_+4=EBO9xd07xhAYQ@mail.gmail.com","threadId":"28990","inReplyTo":"7vk46th5bz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-27T10:13:13Z","receivedAt":"2011-11-27T10:13:13Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Nov 21, 2011 at 10:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> In the medium term, I think one reasonable way forward solving the \"TODO\n> that used to be tracked but now untracked and ignored\" issue is to\n> introduce \"info/exclude-override\" that comes between command line and\n> in-tree patterns. The info/exclude file is designed as the fallback\n> definition to be used when all other sources are too lax, and comes near\n> the precedence stack; the \"TODO\" situation however calls for an override\n> that is stronger than the in-tree patterns.\n\nShort term, should we allow an option to disregard ignored status\n(i.e. all files are precious)? Something like [2/2]\n\n[1/2] checkout,merge: loosen overwriting untracked file check based on\ninfo/exclude\n[2/2] checkout,merge: disallow overwriting ignored files with\n--no-overwrite-ignore\n-- \nDuy\n"},{"id":"180014","messageId":"1322388933-6284-1-git-send-email-pclouds@gmail.com","threadId":"28990","inReplyTo":"CACsJy8AXLBNSPmeEJjD1QX2zF1ic+S9kb_+4=EBO9xd07xhAYQ@mail.gmail.com","subject":"[PATCH 1/2] checkout,merge: loosen overwriting untracked file check based on info/exclude","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-27T10:15:32Z","receivedAt":"2011-11-27T10:15:32Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Back in 1127148 (Loosen \"working file will be lost\" check in\nPorcelain-ish - 2006-12-04), git-checkout.sh learned to quietly\noverwrite ignored files. Howver the code only took .gitignore files\ninto account.\n\nStandard ignored files include all specified in .gitignore files in\nworking directory _and_ $GIT_DIR/info/exclude. This patch makes sure\nignored files in info/exclude can also be overwritten automatically in\nthe spirit of the original patch.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c |    2 +-\n builtin/merge.c    |    2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 2a80772..51840b9 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -411,7 +411,7 @@ static int merge_working_tree(struct checkout_opts *opts,\n \t\ttopts.fn = twoway_merge;\n \t\ttopts.dir = xcalloc(1, sizeof(*topts.dir));\n \t\ttopts.dir->flags |= DIR_SHOW_IGNORED;\n-\t\ttopts.dir->exclude_per_dir = \".gitignore\";\n+\t\tsetup_standard_excludes(topts.dir);\n \t\ttree = parse_tree_indirect(old->commit ?\n \t\t\t\t\t   old->commit->object.sha1 :\n \t\t\t\t\t   EMPTY_TREE_SHA1_BIN);\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 2870a6a..1387376 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -775,7 +775,7 @@ int checkout_fast_forward(const unsigned char *head, const unsigned char *remote\n \tmemset(&t, 0, sizeof(t));\n \tmemset(&dir, 0, sizeof(dir));\n \tdir.flags |= DIR_SHOW_IGNORED;\n-\tdir.exclude_per_dir = \".gitignore\";\n+\tsetup_standard_excludes(&dir);\n \topts.dir = &dir;\n \n \topts.head_idx = 1;\n-- \n1.7.4.74.g639db\n"},{"id":"180015","messageId":"1322388933-6284-2-git-send-email-pclouds@gmail.com","threadId":"28990","inReplyTo":"1322388933-6284-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 2/2] checkout,merge: disallow overwriting ignored files with --no-overwrite-ignore","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-27T10:15:33Z","receivedAt":"2011-11-27T10:15:33Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Ignored files usually are generated files (e.g. .o files) and can be\nsafely discarded. However sometimes users may have important files in\nworking directory, but still want a clean \"git status\", so they mark\nthem as ignored files. But in this case, these files should not be\noverwritten without asking first.\n\nEnable this use case with --no-overwrite-ignore, where git only sees\ntracked and untracked files, no ignored files. Those who mix\ndiscardable ignored files with important ones may have to sort it out\nthemselves.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout.c |   11 ++++++++---\n builtin/merge.c    |   12 ++++++++----\n 2 files changed, 16 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 51840b9..5f9474d 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -34,6 +34,7 @@ struct checkout_opts {\n \tint force_detach;\n \tint writeout_stage;\n \tint writeout_error;\n+\tint overwrite_ignore;\n \n \t/* not set by parse_options */\n \tint branch_exists;\n@@ -409,9 +410,11 @@ static int merge_working_tree(struct checkout_opts *opts,\n \t\ttopts.gently = opts->merge && old->commit;\n \t\ttopts.verbose_update = !opts->quiet;\n \t\ttopts.fn = twoway_merge;\n-\t\ttopts.dir = xcalloc(1, sizeof(*topts.dir));\n-\t\ttopts.dir->flags |= DIR_SHOW_IGNORED;\n-\t\tsetup_standard_excludes(topts.dir);\n+\t\tif (opts->overwrite_ignore) {\n+\t\t\ttopts.dir = xcalloc(1, sizeof(*topts.dir));\n+\t\t\ttopts.dir->flags |= DIR_SHOW_IGNORED;\n+\t\t\tsetup_standard_excludes(topts.dir);\n+\t\t}\n \t\ttree = parse_tree_indirect(old->commit ?\n \t\t\t\t\t   old->commit->object.sha1 :\n \t\t\t\t\t   EMPTY_TREE_SHA1_BIN);\n@@ -926,6 +929,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \t\t\t    3),\n \t\tOPT__FORCE(&opts.force, \"force checkout (throw away local modifications)\"),\n \t\tOPT_BOOLEAN('m', \"merge\", &opts.merge, \"perform a 3-way merge with the new branch\"),\n+\t\tOPT_BOOLEAN(0, \"overwrite-ignore\", &opts.overwrite_ignore, \"update ignored files (default)\"),\n \t\tOPT_STRING(0, \"conflict\", &conflict_style, \"style\",\n \t\t\t   \"conflict style (merge or diff3)\"),\n \t\tOPT_BOOLEAN('p', \"patch\", &patch_mode, \"select hunks interactively\"),\n@@ -937,6 +941,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)\n \n \tmemset(&opts, 0, sizeof(opts));\n \tmemset(&new, 0, sizeof(new));\n+\topts.overwrite_ignore = 1;\n \n \tgitmodules_config();\n \tgit_config(git_checkout_config, &opts);\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 1387376..07102c4 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -48,6 +48,7 @@ static int show_diffstat = 1, shortlog_len, squash;\n static int option_commit = 1, allow_fast_forward = 1;\n static int fast_forward_only, option_edit;\n static int allow_trivial = 1, have_message;\n+static int overwrite_ignore = 1;\n static struct strbuf merge_msg;\n static struct commit_list *remoteheads;\n static struct strategy **use_strategies;\n@@ -207,6 +208,7 @@ static struct option builtin_merge_options[] = {\n \tOPT_BOOLEAN(0, \"abort\", &abort_current_merge,\n \t\t\"abort the current in-progress merge\"),\n \tOPT_SET_INT(0, \"progress\", &show_progress, \"force progress reporting\", 1),\n+\tOPT_BOOLEAN(0, \"overwrite-ignore\", &overwrite_ignore, \"update ignored files (default)\"),\n \tOPT_END()\n };\n \n@@ -773,10 +775,12 @@ int checkout_fast_forward(const unsigned char *head, const unsigned char *remote\n \tmemset(&trees, 0, sizeof(trees));\n \tmemset(&opts, 0, sizeof(opts));\n \tmemset(&t, 0, sizeof(t));\n-\tmemset(&dir, 0, sizeof(dir));\n-\tdir.flags |= DIR_SHOW_IGNORED;\n-\tsetup_standard_excludes(&dir);\n-\topts.dir = &dir;\n+\tif (overwrite_ignore) {\n+\t\tmemset(&dir, 0, sizeof(dir));\n+\t\tdir.flags |= DIR_SHOW_IGNORED;\n+\t\tsetup_standard_excludes(&dir);\n+\t\topts.dir = &dir;\n+\t}\n \n \topts.head_idx = 1;\n \topts.src_index = &the_index;\n-- \n1.7.4.74.g639db\n"},{"id":"180097","messageId":"7v7h2iu72d.fsf@alter.siamese.dyndns.org","threadId":"28990","inReplyTo":"1322388933-6284-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 1/2] checkout,merge: loosen overwriting untracked file check based on info/exclude","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-29T18:17:30Z","receivedAt":"2011-11-29T18:17:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:\n\n> Back in 1127148 (Loosen \"working file will be lost\" check in\n> Porcelain-ish - 2006-12-04), git-checkout.sh learned to quietly\n> overwrite ignored files. Howver the code only took .gitignore files\n> into account.\n\nv1.5.3.5-721-g039bc64 also tried to make it harder to make this kind of\nmistake, and forgot to spot it in git-checkout.sh which was a bit\nunfortunate.\n\nThanks. I think both patches make sense, and especially 2/2 opens the door\nto possibly make ignored ones automatically precious.\n"}]}