{"thread":{"id":"49768","subject":"What exactly is a \"initial checkout\"","startedAt":"2018-11-06T12:38:59Z","lastAt":"2018-11-07T23:34:00Z","messageCount":5,"participants":["Christian Halstrick","Jeff King","Junio C Hamano","Philip Oakley"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"362570","messageId":"CAENte7hoHxQCiQwSaAGPyaeFK8rb2Q23DcbePd01fcvgxtodZg@mail.gmail.com","threadId":"49768","inReplyTo":null,"subject":"What exactly is a \"initial checkout\"","fromName":"Christian Halstrick","fromEmail":"christian.halstrick@gmail.com","sentAt":"2018-11-06T12:38:45Z","receivedAt":"2018-11-06T12:38:59Z","isPatch":false,"sender":{"key":"christian.halstrick@gmail.com","avatar":"https://gravatar.com/avatar/3598bf518644c7dc32d4dcd8e0554b6a313e12103011862402c83ae2854203ce?d=mp&s=160"},"body":"I am trying to teach JGit [1] to behave like native git regarding some\ncorner cases during \"git checkout\". I am reading the \"git read-tree\"\ndocumentation and I am not sure about the case [2]. Git should behave\ndifferently during a normal checkout than when you are doing a\n\"initial checkout\". I can imagine that the first checkout you do after\nyou have cloned a repo is a initial checkout but: What exactly defines\na \"initial checkout\"? It can't be an empty or non-existing index\nbecause native git behaves like in a non-initial-checkout even if the\nindex is empty (see example below).\n\nHere are some commands explaining my case. Git is facing an empty\nindex, HEAD and MERGE (the commit you checkout) have the some content\nfor path 'p'  and still git is neither updating index nor workingtree\nfile during checkout.\n\ngit init\nmkdir p\necho initial >p/a\ngit add p/a\ngit commit -m initial\ntouch p2\ngit add p2\ngit commit -m followup\ngit rm -r p p2\necho \"important data\" >p\ngit checkout HEAD~ # successful checkout leaving p dirty\ncat p # prints \"important data\", so 'p' is not updated during the checkout\ngit ls-files -sv  # empty -> index is empty\n\n[1] https://www.eclipse.org/jgit/\n[2] https://github.com/git/git/blob/master/Documentation/git-read-tree.txt#L187\n"},{"id":"362613","messageId":"20181106211852.GA8513@sigill.intra.peff.net","threadId":"49768","inReplyTo":"CAENte7hoHxQCiQwSaAGPyaeFK8rb2Q23DcbePd01fcvgxtodZg@mail.gmail.com","subject":"Re: What exactly is a \"initial checkout\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-11-06T21:18:52Z","receivedAt":"2018-11-06T21:18:56Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Nov 06, 2018 at 01:38:45PM +0100, Christian Halstrick wrote:\n\n> I am trying to teach JGit [1] to behave like native git regarding some\n> corner cases during \"git checkout\". I am reading the \"git read-tree\"\n> documentation and I am not sure about the case [2]. Git should behave\n> differently during a normal checkout than when you are doing a\n> \"initial checkout\". I can imagine that the first checkout you do after\n> you have cloned a repo is a initial checkout but: What exactly defines\n> a \"initial checkout\"? It can't be an empty or non-existing index\n> because native git behaves like in a non-initial-checkout even if the\n> index is empty (see example below).\n> \n> Here are some commands explaining my case. Git is facing an empty\n> index, HEAD and MERGE (the commit you checkout) have the some content\n> for path 'p'  and still git is neither updating index nor workingtree\n> file during checkout.\n\nWithout looking at the code, I'd assume that an empty HEAD is different\nthan \"there is no HEAD at all\". I.e., what we call an \"unborn branch\"\nelsewhere.\n\nSo perhaps try:\n\n  git init\n  git fetch ../some/other/repo HEAD:tmp\n  git checkout tmp\n\nwhere you'd truly have no HEAD.\n\nThough peeking at the code, it looks like we set the unpack_trees\ninitial_checkout flag based on is_cache_unborn(), which looks for a\ntotally missing index file (not just an empty one). That would trigger\nin the above case, too, though, because of course we have no index there\neither.\n\n-Peff\n"},{"id":"362619","messageId":"xmqqa7mleond.fsf@gitster-ct.c.googlers.com","threadId":"49768","inReplyTo":"CAENte7hoHxQCiQwSaAGPyaeFK8rb2Q23DcbePd01fcvgxtodZg@mail.gmail.com","subject":"Re: What exactly is a \"initial checkout\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-07T00:07:18Z","receivedAt":"2018-11-07T00:07:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Halstrick <christian.halstrick@gmail.com> writes:\n\n> I am trying to teach JGit [1] to behave like native git regarding some\n> corner cases during \"git checkout\". I am reading the \"git read-tree\"\n> documentation and I am not sure about the case [2]. Git should behave\n> differently during a normal checkout than when you are doing a\n> \"initial checkout\".\n\nWhen you are starting from commit H and checking out a different\ncommit M, and when a path in the index does not match what is\nrecorded in commit H, usually Git tries to keep the state of the\npath you have in your index as a \"local change\", as long as the data\nrecorded for the path is the same between H and M.  A path in the\nindex that matches what is recorded in commit H and with different\ndata recorded for it in commit M gets M's version in the index and\nthe working file is updated to match (but it requires that either\nthe working tree file is missing, or the working tree version\nmatches what is in the original index, to avoid data loss).\n\nBut imagine you have just cloned and are trying to finish that\nprocess.  What Git has done so far would include creating an empty\nrepository, populating the object database and pointing branches at\nvarious commits.  HEAD now points at the branch (usually 'master'),\nthe index file does not exist (you haven't checked out anything),\nand we want to populate the index and the working tree files to\nmatch what is recorded in HEAD.  We do so by starting from commit\nHEAD and checking out commit HEAD.\n\nThis situation presents conflicting goals to the above \"keep the\nlocal change\" rule.  To the rule, this situation looks as if you\nremoved each and every path from the index (as the index hasn't been\npopulated yet---in fact, the index file does not even exist yet in\nthis state), but the data recorded for each path are the same\nbetween commit H and commit M (as H==M==HEAD in this case), so \"keep\nthe local change\" rule would leave the index and the working tree\nempty X-<.\n\nThat is rescued by the \"initial checkout behaves differently and\nforces the index and the working tree match what is recorded in\ncommit M\" exception.  It probably should be obvious to the readers\nby now that the absense of .git/index is used as the clue for this\nexception to kick in from the above use case.\n\nAnd that is exactly the condition that is checked by\nread-cache.c::is_index_unborn().\n\n"},{"id":"362632","messageId":"CAENte7hN6=ChSWHKo=cawvwV_2xVDW0uCRY+yAjAgCz8_TtpmA@mail.gmail.com","threadId":"49768","inReplyTo":"xmqqa7mleond.fsf@gitster-ct.c.googlers.com","subject":"Re: What exactly is a \"initial checkout\"","fromName":"Christian Halstrick","fromEmail":"christian.halstrick@gmail.com","sentAt":"2018-11-07T08:50:34Z","receivedAt":"2018-11-07T08:50:48Z","isPatch":false,"sender":{"key":"christian.halstrick@gmail.com","avatar":"https://gravatar.com/avatar/3598bf518644c7dc32d4dcd8e0554b6a313e12103011862402c83ae2854203ce?d=mp&s=160"},"body":"Ok, I know understand the problems which are solved by this\nspecial behaviour of a \"initial checkout\". And also important I understand\nwhen exactly I should do a \"initial checkout\" - when the index file does\nnot exist. I'll share my new knowledge with JGit :-)\n"},{"id":"362680","messageId":"f81eb37d-e432-7451-6472-7ddc0874d0c7@talktalk.net","threadId":"49768","inReplyTo":"CAENte7hN6=ChSWHKo=cawvwV_2xVDW0uCRY+yAjAgCz8_TtpmA@mail.gmail.com","subject":"Re: What exactly is a \"initial checkout\"","fromName":"Philip Oakley","fromEmail":"philipoakley@talktalk.net","sentAt":"2018-11-07T23:33:56Z","receivedAt":"2018-11-07T23:34:00Z","isPatch":false,"sender":{"key":"philipoakley@talktalk.net","avatar":null},"body":"On 07/11/2018 08:50, Christian Halstrick wrote:\n> Ok, I know understand the problems which are solved by this\n> special behaviour of a \"initial checkout\". And also important I understand\n> when exactly I should do a \"initial checkout\" - when the index file does\n> not exist. I'll share my new knowledge with JGit :-)\n> \nGiven that the initial query was about the lack of documentation for the \nterm \"initial checkout\", do you have any suggestion of how it might best \nbe incorporated into the documentation to assist future reader?\n-- \nPhilip\n"}]}