{"thread":{"id":"15833","subject":"[RFD] Sparse checkout, unmerged entries and \"reset --hard\"","startedAt":"2008-10-09T13:45:18Z","lastAt":"2008-10-09T13:45:18Z","messageCount":1,"participants":["Nguyen Thai Ngoc Duy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"92669","messageId":"fcaeb9bf0810090645x29626b45j16d0e0e17fe93810@mail.gmail.com","threadId":"15833","inReplyTo":null,"subject":"[RFD] Sparse checkout, unmerged entries and \"reset --hard\"","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2008-10-09T13:45:18Z","receivedAt":"2008-10-09T13:45:18Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Hi,\n\nThere is a problem with those things and I don't know how to handle\nit. In brief, in \"git reset --hard\" (or \"git read-tree --reset\"),\nunmerged entries will be removed from in-memory index, so merge\nprocess does not see them and re-add them like new entries. But with\nsparse checkout, \"new entries\" and \"merged entries\" are handled\ndifferently. This may lead to stale/orphaned entries.\n\nThe detail:\n\n 1. unmerged entries are filtered out from cmd_read_tree() if --reset\nis provided.\n 2. inside unpack_trees(), [1-3]way_merge() pass src[0] (which is NULL\nin unmerged cases) to merged_entry()\n 3. merged_entry() sees it as \"no old entry so this must be new\nentry\", it makes sure there is no real file in working directory, but\nthen the check is ignored in --reset mode.\n 4. entries get added as new ones.\n\nWith sparse checkout, in the last two steps, it would check if new\nentry matches default sparse pattern (which determines if the entry\nshould be added to working directory). In case it decides the entry\nshould not be added to working directory, it would remove CE_UPDATE\nflag from the entry. This is fine for _true_ new entries. But in\nunmerged case, it would leave a stale/orphaned entry in working\ndirectory while it is marked no-checkout in index.\n\nI would expect sparse checkout work correctly even in unmerged case.\nThat is the entry is removed from working directory (if outside sparse\npattern), staged entries are removed in index, stage 0 entry is added\nwith no-checkout flag.\n\nComments? Maybe doing a two-phase merge (unmerged entries first, the\nrest later)?\n-- \nDuy\n"}]}