{"thread":{"id":"61464","subject":"Checkout to different directory at certain commit without changing index","startedAt":"2024-05-13T07:26:13Z","lastAt":"2024-05-15T05:07:16Z","messageCount":7,"participants":["Ondra Medek","Phillip Wood","phillip.wood123@gmail.com"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"494567","messageId":"CAJsoDaEJn1Y0CgtxpkGqVRsTiDnMxjNFrtbTuUVOvT87N23JNg@mail.gmail.com","threadId":"61464","inReplyTo":null,"subject":"Checkout to different directory at certain commit without changing index","fromName":"Ondra Medek","fromEmail":"xmedeko@gmail.com","sentAt":"2024-05-13T07:26:00Z","receivedAt":"2024-05-13T07:26:13Z","isPatch":false,"sender":{"key":"xmedeko@gmail.com","avatar":"https://gravatar.com/avatar/09ec305680e81ade2e3617fd245cda7136f6d5e859b5120feb9436e0725f6e1d?d=mp&s=160"},"body":"Hello,\nI need a simple script for unskilled users to do a fast checkout (LFS\nfriendly) of the current local Git clone at a certain commit to a\ndifferent directory I.e. something like \"copy at a point in history\".\nIMO all possible solutions are summarized in this thread\nhttps://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export\nI describe some of them with my remarks:\n\n- git checkout-index : works with HEAD only.\n- git archive: influenced by export-ignore and export-subst\nattributes, so may not produce exact copy of sources. (And needs tar).\n- git worktree add -d : needs cleanup: git prune or git remove.\n- git clone: Unfortunately, -b param cannot work with commit hash and\ndoes not respect local worktree settings (e.g. autocrlf). So, a\nsolution may be a bit complicated: git clone -s -n . dest/path ; cp\n.git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;\nrm -rf .git\n- git checkout: Unfortunately, modifies Git index, so some action to\nrevert index is necessary after: git --work-tree=/path/to/checkout/\ncheckout -f -q <tree-ish> -- ./\n\nFor me, the best solution is with git clone, because it does not\nmodify Git index nor any source working tree settings, so no cleanup\nis necessary. But it's a bit complicated, though. It seems to me that\n\"git checkout\" could do this better and simpler if it would have some\nparam to not modify the Git index. Is it possible to enhance git\ncheckout? Or is there any other simple solution not mentioned in the\nSO thread?\n\nThank you\nOndra Medek\n"},{"id":"494635","messageId":"13fa579b-8987-4430-967c-42b9de8acb6d@gmail.com","threadId":"61464","inReplyTo":"CAJsoDaEJn1Y0CgtxpkGqVRsTiDnMxjNFrtbTuUVOvT87N23JNg@mail.gmail.com","subject":"Re: Checkout to different directory at certain commit without changing index","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-05-13T15:28:44Z","receivedAt":"2024-05-13T15:28:49Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Ondra\n\nOn 13/05/2024 08:26, Ondra Medek wrote:\n> Hello,\n> I need a simple script for unskilled users to do a fast checkout (LFS\n> friendly) of the current local Git clone at a certain commit to a\n> different directory I.e. something like \"copy at a point in history\".\n\nI think using\n\n     git archive \"$commit\" --format=tar |\n        { cd \"$output_directory\" && tar -xf -; }\n\nis probably the simplest solution. If you don't want to rely on tar then \nsomething like\n\n     GIT_DIR=\"$(git rev-parse --path-format=absolute --git-dir)\" &&\n     GIT_COMMON_DIR=\"$(git rev-parse --path-format=absolute \n--git-common-dir)\" || exit\n     GIT_INDEX_FILE=\"$GIT_DIR/tmp-index-$$\"\n     export GIT_DIR GIT_COMMON_DIR GIT_INDEX_FILE\n     unset GIT_WORK_TREE\n     mkdir \"$output_directory\" && cd \"$output_directory\" &&\n     git read-tree -u \"$commit\"\n     status=$?\n     rm \"$GIT_INDEX_FILE\"\n     exit $status\n\nWhich uses a temporary index file should work (note I haven't tested \nit). You may want to add \"--recurse-submodules\" and/or \n\"--no-sparse-checkout\" to the \"git read-tree\" commandline.\n\nBest Wishes\n\nPhillip\n\n> IMO all possible solutions are summarized in this thread\n> https://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export\n> I describe some of them with my remarks:\n> \n> - git checkout-index : works with HEAD only.\n> - git archive: influenced by export-ignore and export-subst\n> attributes, so may not produce exact copy of sources. (And needs tar).\n> - git worktree add -d : needs cleanup: git prune or git remove.\n> - git clone: Unfortunately, -b param cannot work with commit hash and\n> does not respect local worktree settings (e.g. autocrlf). So, a\n> solution may be a bit complicated: git clone -s -n . dest/path ; cp\n> .git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;\n> rm -rf .git\n> - git checkout: Unfortunately, modifies Git index, so some action to\n> revert index is necessary after: git --work-tree=/path/to/checkout/\n> checkout -f -q <tree-ish> -- ./\n> \n> For me, the best solution is with git clone, because it does not\n> modify Git index nor any source working tree settings, so no cleanup\n> is necessary. But it's a bit complicated, though. It seems to me that\n> \"git checkout\" could do this better and simpler if it would have some\n> param to not modify the Git index. Is it possible to enhance git\n> checkout? Or is there any other simple solution not mentioned in the\n> SO thread?\n> \n> Thank you\n> Ondra Medek\n> \n"},{"id":"494641","messageId":"CAJsoDaFhTcm0fEw3+Ba4PvTjPYxscALeLN2kBgs4YYz8Bg-R7g@mail.gmail.com","threadId":"61464","inReplyTo":"13fa579b-8987-4430-967c-42b9de8acb6d@gmail.com","subject":"Re: Checkout to different directory at certain commit without changing index","fromName":"Ondra Medek","fromEmail":"xmedeko@gmail.com","sentAt":"2024-05-13T17:23:17Z","receivedAt":"2024-05-13T17:23:29Z","isPatch":false,"sender":{"key":"xmedeko@gmail.com","avatar":"https://gravatar.com/avatar/09ec305680e81ade2e3617fd245cda7136f6d5e859b5120feb9436e0725f6e1d?d=mp&s=160"},"body":"Hi Phillip,\n\nbesides dependency on tar, I do not want to use git-archive because\nit's influenced by export-ignore and export-subst attributes, too (as\nI have mentioned).\n\nThanks for git read-tree, seems it's exactly what I need. Just git\nread-tree has complained that -u switch needs -m or --reset switches.\nAnd I have simplified it to\n\ngit --work-tree=\"$destdir\" read-tree --index-output=\"$destdir\".git -u\n--reset \"$commit\"\nrm -f \"$destdir\"/.git\n\nMay I post this solution to the SO thread I have mentioned?\n\nThanks very much\n\nOndra\n\nOn Mon, 13 May 2024 at 17:28, Phillip Wood <phillip.wood123@gmail.com> wrote:\n>\n> Hi Ondra\n>\n> On 13/05/2024 08:26, Ondra Medek wrote:\n> > Hello,\n> > I need a simple script for unskilled users to do a fast checkout (LFS\n> > friendly) of the current local Git clone at a certain commit to a\n> > different directory I.e. something like \"copy at a point in history\".\n>\n> I think using\n>\n>      git archive \"$commit\" --format=tar |\n>         { cd \"$output_directory\" && tar -xf -; }\n>\n> is probably the simplest solution. If you don't want to rely on tar then\n> something like\n>\n>      GIT_DIR=\"$(git rev-parse --path-format=absolute --git-dir)\" &&\n>      GIT_COMMON_DIR=\"$(git rev-parse --path-format=absolute\n> --git-common-dir)\" || exit\n>      GIT_INDEX_FILE=\"$GIT_DIR/tmp-index-$$\"\n>      export GIT_DIR GIT_COMMON_DIR GIT_INDEX_FILE\n>      unset GIT_WORK_TREE\n>      mkdir \"$output_directory\" && cd \"$output_directory\" &&\n>      git read-tree -u \"$commit\"\n>      status=$?\n>      rm \"$GIT_INDEX_FILE\"\n>      exit $status\n>\n> Which uses a temporary index file should work (note I haven't tested\n> it). You may want to add \"--recurse-submodules\" and/or\n> \"--no-sparse-checkout\" to the \"git read-tree\" commandline.\n>\n> Best Wishes\n>\n> Phillip\n>\n> > IMO all possible solutions are summarized in this thread\n> > https://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export\n> > I describe some of them with my remarks:\n> >\n> > - git checkout-index : works with HEAD only.\n> > - git archive: influenced by export-ignore and export-subst\n> > attributes, so may not produce exact copy of sources. (And needs tar).\n> > - git worktree add -d : needs cleanup: git prune or git remove.\n> > - git clone: Unfortunately, -b param cannot work with commit hash and\n> > does not respect local worktree settings (e.g. autocrlf). So, a\n> > solution may be a bit complicated: git clone -s -n . dest/path ; cp\n> > .git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;\n> > rm -rf .git\n> > - git checkout: Unfortunately, modifies Git index, so some action to\n> > revert index is necessary after: git --work-tree=/path/to/checkout/\n> > checkout -f -q <tree-ish> -- ./\n> >\n> > For me, the best solution is with git clone, because it does not\n> > modify Git index nor any source working tree settings, so no cleanup\n> > is necessary. But it's a bit complicated, though. It seems to me that\n> > \"git checkout\" could do this better and simpler if it would have some\n> > param to not modify the Git index. Is it possible to enhance git\n> > checkout? Or is there any other simple solution not mentioned in the\n> > SO thread?\n> >\n> > Thank you\n> > Ondra Medek\n> >\n"},{"id":"494700","messageId":"CAJsoDaHu1xgfwXHqOGgctQoi5Qb5D1aESeMvaVHaQV0zjyzRRg@mail.gmail.com","threadId":"61464","inReplyTo":"CAJsoDaFhTcm0fEw3+Ba4PvTjPYxscALeLN2kBgs4YYz8Bg-R7g@mail.gmail.com","subject":"Re: Checkout to different directory at certain commit without changing index","fromName":"Ondra Medek","fromEmail":"xmedeko@gmail.com","sentAt":"2024-05-14T06:29:45Z","receivedAt":"2024-05-14T06:29:57Z","isPatch":false,"sender":{"key":"xmedeko@gmail.com","avatar":"https://gravatar.com/avatar/09ec305680e81ade2e3617fd245cda7136f6d5e859b5120feb9436e0725f6e1d?d=mp&s=160"},"body":"Hi Phillip,\n\nyour trick with different index file works with git checkout, too, e.g.\n\nGIT_INDEX_FILE=\"$destdir\"/.git git --work-tree=\"$destdir\" checkout -f\n-q \"$commit\" -- ./\nrm -f \"$destdir\"/.git\n\nSincerely\nOndra\n\nOn Mon, 13 May 2024 at 19:23, Ondra Medek <xmedeko@gmail.com> wrote:\n>\n> Hi Phillip,\n>\n> besides dependency on tar, I do not want to use git-archive because\n> it's influenced by export-ignore and export-subst attributes, too (as\n> I have mentioned).\n>\n> Thanks for git read-tree, seems it's exactly what I need. Just git\n> read-tree has complained that -u switch needs -m or --reset switches.\n> And I have simplified it to\n>\n> git --work-tree=\"$destdir\" read-tree --index-output=\"$destdir\".git -u\n> --reset \"$commit\"\n> rm -f \"$destdir\"/.git\n>\n> May I post this solution to the SO thread I have mentioned?\n>\n> Thanks very much\n>\n> Ondra\n>\n> On Mon, 13 May 2024 at 17:28, Phillip Wood <phillip.wood123@gmail.com> wrote:\n> >\n> > Hi Ondra\n> >\n> > On 13/05/2024 08:26, Ondra Medek wrote:\n> > > Hello,\n> > > I need a simple script for unskilled users to do a fast checkout (LFS\n> > > friendly) of the current local Git clone at a certain commit to a\n> > > different directory I.e. something like \"copy at a point in history\".\n> >\n> > I think using\n> >\n> >      git archive \"$commit\" --format=tar |\n> >         { cd \"$output_directory\" && tar -xf -; }\n> >\n> > is probably the simplest solution. If you don't want to rely on tar then\n> > something like\n> >\n> >      GIT_DIR=\"$(git rev-parse --path-format=absolute --git-dir)\" &&\n> >      GIT_COMMON_DIR=\"$(git rev-parse --path-format=absolute\n> > --git-common-dir)\" || exit\n> >      GIT_INDEX_FILE=\"$GIT_DIR/tmp-index-$$\"\n> >      export GIT_DIR GIT_COMMON_DIR GIT_INDEX_FILE\n> >      unset GIT_WORK_TREE\n> >      mkdir \"$output_directory\" && cd \"$output_directory\" &&\n> >      git read-tree -u \"$commit\"\n> >      status=$?\n> >      rm \"$GIT_INDEX_FILE\"\n> >      exit $status\n> >\n> > Which uses a temporary index file should work (note I haven't tested\n> > it). You may want to add \"--recurse-submodules\" and/or\n> > \"--no-sparse-checkout\" to the \"git read-tree\" commandline.\n> >\n> > Best Wishes\n> >\n> > Phillip\n> >\n> > > IMO all possible solutions are summarized in this thread\n> > > https://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export\n> > > I describe some of them with my remarks:\n> > >\n> > > - git checkout-index : works with HEAD only.\n> > > - git archive: influenced by export-ignore and export-subst\n> > > attributes, so may not produce exact copy of sources. (And needs tar).\n> > > - git worktree add -d : needs cleanup: git prune or git remove.\n> > > - git clone: Unfortunately, -b param cannot work with commit hash and\n> > > does not respect local worktree settings (e.g. autocrlf). So, a\n> > > solution may be a bit complicated: git clone -s -n . dest/path ; cp\n> > > .git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;\n> > > rm -rf .git\n> > > - git checkout: Unfortunately, modifies Git index, so some action to\n> > > revert index is necessary after: git --work-tree=/path/to/checkout/\n> > > checkout -f -q <tree-ish> -- ./\n> > >\n> > > For me, the best solution is with git clone, because it does not\n> > > modify Git index nor any source working tree settings, so no cleanup\n> > > is necessary. But it's a bit complicated, though. It seems to me that\n> > > \"git checkout\" could do this better and simpler if it would have some\n> > > param to not modify the Git index. Is it possible to enhance git\n> > > checkout? Or is there any other simple solution not mentioned in the\n> > > SO thread?\n> > >\n> > > Thank you\n> > > Ondra Medek\n> > >\n"},{"id":"494704","messageId":"45674580-e7f6-48aa-ac17-3e0b96acace9@gmail.com","threadId":"61464","inReplyTo":"CAJsoDaFhTcm0fEw3+Ba4PvTjPYxscALeLN2kBgs4YYz8Bg-R7g@mail.gmail.com","subject":"Re: Checkout to different directory at certain commit without changing index","fromName":"","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-05-14T10:01:36Z","receivedAt":"2024-05-14T10:01:38Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Ondra\n\nOn 13/05/2024 18:23, Ondra Medek wrote:\n> Hi Phillip,\n> \n> besides dependency on tar, I do not want to use git-archive because\n> it's influenced by export-ignore and export-subst attributes, too (as\n> I have mentioned).\n> \n> Thanks for git read-tree, seems it's exactly what I need. Just git\n> read-tree has complained that -u switch needs -m or --reset switches.\n> And I have simplified it to\n\nSorry I'd forgotten about that\n\n> git --work-tree=\"$destdir\" read-tree --index-output=\"$destdir\".git -u\n> --reset \"$commit\"\n\nYou should be aware that --reset will happily overwrite files in the \ndestination directory, using -m instead would stop existing files being \noverwritten. If you change to -m you must set GIT_INDEX_FILE instead of \nusing --index-output otherwise only the files that differ from the \ncurrent index will be checked out. Also using a relative path for the \nindex file specified with --index-output or GIT_INDEX_FILE is error \nprone when running the command from a subdirectory of the repository. I \navoided suggesting --work-tree because I wasn't sure how it handled \nrelative paths when run from a subdirectory but I think it is in fact ok.\n\n> rm -f \"$destdir\"/.git\n> \n> May I post this solution to the SO thread I have mentioned?\n\nThat's entirely up to you but I'd make sure it works with relative paths \nand note the difference between --reset and -m.\n\nBest Wishes\n\nPhillip\n\n> Thanks very much\n> \n> Ondra\n> \n> On Mon, 13 May 2024 at 17:28, Phillip Wood <phillip.wood123@gmail.com> wrote:\n>>\n>> Hi Ondra\n>>\n>> On 13/05/2024 08:26, Ondra Medek wrote:\n>>> Hello,\n>>> I need a simple script for unskilled users to do a fast checkout (LFS\n>>> friendly) of the current local Git clone at a certain commit to a\n>>> different directory I.e. something like \"copy at a point in history\".\n>>\n>> I think using\n>>\n>>       git archive \"$commit\" --format=tar |\n>>          { cd \"$output_directory\" && tar -xf -; }\n>>\n>> is probably the simplest solution. If you don't want to rely on tar then\n>> something like\n>>\n>>       GIT_DIR=\"$(git rev-parse --path-format=absolute --git-dir)\" &&\n>>       GIT_COMMON_DIR=\"$(git rev-parse --path-format=absolute\n>> --git-common-dir)\" || exit\n>>       GIT_INDEX_FILE=\"$GIT_DIR/tmp-index-$$\"\n>>       export GIT_DIR GIT_COMMON_DIR GIT_INDEX_FILE\n>>       unset GIT_WORK_TREE\n>>       mkdir \"$output_directory\" && cd \"$output_directory\" &&\n>>       git read-tree -u \"$commit\"\n>>       status=$?\n>>       rm \"$GIT_INDEX_FILE\"\n>>       exit $status\n>>\n>> Which uses a temporary index file should work (note I haven't tested\n>> it). You may want to add \"--recurse-submodules\" and/or\n>> \"--no-sparse-checkout\" to the \"git read-tree\" commandline.\n>>\n>> Best Wishes\n>>\n>> Phillip\n>>\n>>> IMO all possible solutions are summarized in this thread\n>>> https://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export\n>>> I describe some of them with my remarks:\n>>>\n>>> - git checkout-index : works with HEAD only.\n>>> - git archive: influenced by export-ignore and export-subst\n>>> attributes, so may not produce exact copy of sources. (And needs tar).\n>>> - git worktree add -d : needs cleanup: git prune or git remove.\n>>> - git clone: Unfortunately, -b param cannot work with commit hash and\n>>> does not respect local worktree settings (e.g. autocrlf). So, a\n>>> solution may be a bit complicated: git clone -s -n . dest/path ; cp\n>>> .git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;\n>>> rm -rf .git\n>>> - git checkout: Unfortunately, modifies Git index, so some action to\n>>> revert index is necessary after: git --work-tree=/path/to/checkout/\n>>> checkout -f -q <tree-ish> -- ./\n>>>\n>>> For me, the best solution is with git clone, because it does not\n>>> modify Git index nor any source working tree settings, so no cleanup\n>>> is necessary. But it's a bit complicated, though. It seems to me that\n>>> \"git checkout\" could do this better and simpler if it would have some\n>>> param to not modify the Git index. Is it possible to enhance git\n>>> checkout? Or is there any other simple solution not mentioned in the\n>>> SO thread?\n>>>\n>>> Thank you\n>>> Ondra Medek\n>>>\n"},{"id":"494705","messageId":"89b83e3d-dd38-4b3b-8f87-6ac739e4e12f@gmail.com","threadId":"61464","inReplyTo":"CAJsoDaHu1xgfwXHqOGgctQoi5Qb5D1aESeMvaVHaQV0zjyzRRg@mail.gmail.com","subject":"Re: Checkout to different directory at certain commit without changing index","fromName":"","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-05-14T10:07:01Z","receivedAt":"2024-05-14T10:07:03Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Ondra\n\nOn 14/05/2024 07:29, Ondra Medek wrote:\n> Hi Phillip,\n> \n> your trick with different index file works with git checkout, too, e.g.\n> \n> GIT_INDEX_FILE=\"$destdir\"/.git git --work-tree=\"$destdir\" checkout -f\n> -q \"$commit\" -- ./\n> rm -f \"$destdir\"/.git\n\nI'd not thought of that, presumably \"git restore\" would work as well. \nUsing \"./\" means it will only work from the repository root, you can use \nthe pathmagic \":/\" instead to checkout everything when it is run from a \nsubdirectory  but you need to make sure GIT_INDEX_FILE is an absolute path.\n\nBest Wishes\n\nPhillip\n\n> Sincerely\n> Ondra\n> \n> On Mon, 13 May 2024 at 19:23, Ondra Medek <xmedeko@gmail.com> wrote:\n>>\n>> Hi Phillip,\n>>\n>> besides dependency on tar, I do not want to use git-archive because\n>> it's influenced by export-ignore and export-subst attributes, too (as\n>> I have mentioned).\n>>\n>> Thanks for git read-tree, seems it's exactly what I need. Just git\n>> read-tree has complained that -u switch needs -m or --reset switches.\n>> And I have simplified it to\n>>\n>> git --work-tree=\"$destdir\" read-tree --index-output=\"$destdir\".git -u\n>> --reset \"$commit\"\n>> rm -f \"$destdir\"/.git\n>>\n>> May I post this solution to the SO thread I have mentioned?\n>>\n>> Thanks very much\n>>\n>> Ondra\n>>\n>> On Mon, 13 May 2024 at 17:28, Phillip Wood <phillip.wood123@gmail.com> wrote:\n>>>\n>>> Hi Ondra\n>>>\n>>> On 13/05/2024 08:26, Ondra Medek wrote:\n>>>> Hello,\n>>>> I need a simple script for unskilled users to do a fast checkout (LFS\n>>>> friendly) of the current local Git clone at a certain commit to a\n>>>> different directory I.e. something like \"copy at a point in history\".\n>>>\n>>> I think using\n>>>\n>>>       git archive \"$commit\" --format=tar |\n>>>          { cd \"$output_directory\" && tar -xf -; }\n>>>\n>>> is probably the simplest solution. If you don't want to rely on tar then\n>>> something like\n>>>\n>>>       GIT_DIR=\"$(git rev-parse --path-format=absolute --git-dir)\" &&\n>>>       GIT_COMMON_DIR=\"$(git rev-parse --path-format=absolute\n>>> --git-common-dir)\" || exit\n>>>       GIT_INDEX_FILE=\"$GIT_DIR/tmp-index-$$\"\n>>>       export GIT_DIR GIT_COMMON_DIR GIT_INDEX_FILE\n>>>       unset GIT_WORK_TREE\n>>>       mkdir \"$output_directory\" && cd \"$output_directory\" &&\n>>>       git read-tree -u \"$commit\"\n>>>       status=$?\n>>>       rm \"$GIT_INDEX_FILE\"\n>>>       exit $status\n>>>\n>>> Which uses a temporary index file should work (note I haven't tested\n>>> it). You may want to add \"--recurse-submodules\" and/or\n>>> \"--no-sparse-checkout\" to the \"git read-tree\" commandline.\n>>>\n>>> Best Wishes\n>>>\n>>> Phillip\n>>>\n>>>> IMO all possible solutions are summarized in this thread\n>>>> https://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export\n>>>> I describe some of them with my remarks:\n>>>>\n>>>> - git checkout-index : works with HEAD only.\n>>>> - git archive: influenced by export-ignore and export-subst\n>>>> attributes, so may not produce exact copy of sources. (And needs tar).\n>>>> - git worktree add -d : needs cleanup: git prune or git remove.\n>>>> - git clone: Unfortunately, -b param cannot work with commit hash and\n>>>> does not respect local worktree settings (e.g. autocrlf). So, a\n>>>> solution may be a bit complicated: git clone -s -n . dest/path ; cp\n>>>> .git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;\n>>>> rm -rf .git\n>>>> - git checkout: Unfortunately, modifies Git index, so some action to\n>>>> revert index is necessary after: git --work-tree=/path/to/checkout/\n>>>> checkout -f -q <tree-ish> -- ./\n>>>>\n>>>> For me, the best solution is with git clone, because it does not\n>>>> modify Git index nor any source working tree settings, so no cleanup\n>>>> is necessary. But it's a bit complicated, though. It seems to me that\n>>>> \"git checkout\" could do this better and simpler if it would have some\n>>>> param to not modify the Git index. Is it possible to enhance git\n>>>> checkout? Or is there any other simple solution not mentioned in the\n>>>> SO thread?\n>>>>\n>>>> Thank you\n>>>> Ondra Medek\n>>>>\n"},{"id":"494756","messageId":"CAJsoDaGFh-51y4HJnmDo1t44qLR9zU2q10qoBceYCDbLEv4hZg@mail.gmail.com","threadId":"61464","inReplyTo":"89b83e3d-dd38-4b3b-8f87-6ac739e4e12f@gmail.com","subject":"Re: Checkout to different directory at certain commit without changing index","fromName":"Ondra Medek","fromEmail":"xmedeko@gmail.com","sentAt":"2024-05-15T05:07:03Z","receivedAt":"2024-05-15T05:07:16Z","isPatch":false,"sender":{"key":"xmedeko@gmail.com","avatar":"https://gravatar.com/avatar/09ec305680e81ade2e3617fd245cda7136f6d5e859b5120feb9436e0725f6e1d?d=mp&s=160"},"body":"Hi Phillip,\nthanks for your insightful advice.\nOndra\n\nOn Tue, 14 May 2024 at 12:07, <phillip.wood123@gmail.com> wrote:\n>\n> Hi Ondra\n>\n> On 14/05/2024 07:29, Ondra Medek wrote:\n> > Hi Phillip,\n> >\n> > your trick with different index file works with git checkout, too, e.g.\n> >\n> > GIT_INDEX_FILE=\"$destdir\"/.git git --work-tree=\"$destdir\" checkout -f\n> > -q \"$commit\" -- ./\n> > rm -f \"$destdir\"/.git\n>\n> I'd not thought of that, presumably \"git restore\" would work as well.\n> Using \"./\" means it will only work from the repository root, you can use\n> the pathmagic \":/\" instead to checkout everything when it is run from a\n> subdirectory  but you need to make sure GIT_INDEX_FILE is an absolute path.\n>\n> Best Wishes\n>\n> Phillip\n>\n> > Sincerely\n> > Ondra\n> >\n> > On Mon, 13 May 2024 at 19:23, Ondra Medek <xmedeko@gmail.com> wrote:\n> >>\n> >> Hi Phillip,\n> >>\n> >> besides dependency on tar, I do not want to use git-archive because\n> >> it's influenced by export-ignore and export-subst attributes, too (as\n> >> I have mentioned).\n> >>\n> >> Thanks for git read-tree, seems it's exactly what I need. Just git\n> >> read-tree has complained that -u switch needs -m or --reset switches.\n> >> And I have simplified it to\n> >>\n> >> git --work-tree=\"$destdir\" read-tree --index-output=\"$destdir\".git -u\n> >> --reset \"$commit\"\n> >> rm -f \"$destdir\"/.git\n> >>\n> >> May I post this solution to the SO thread I have mentioned?\n> >>\n> >> Thanks very much\n> >>\n> >> Ondra\n> >>\n> >> On Mon, 13 May 2024 at 17:28, Phillip Wood <phillip.wood123@gmail.com> wrote:\n> >>>\n> >>> Hi Ondra\n> >>>\n> >>> On 13/05/2024 08:26, Ondra Medek wrote:\n> >>>> Hello,\n> >>>> I need a simple script for unskilled users to do a fast checkout (LFS\n> >>>> friendly) of the current local Git clone at a certain commit to a\n> >>>> different directory I.e. something like \"copy at a point in history\".\n> >>>\n> >>> I think using\n> >>>\n> >>>       git archive \"$commit\" --format=tar |\n> >>>          { cd \"$output_directory\" && tar -xf -; }\n> >>>\n> >>> is probably the simplest solution. If you don't want to rely on tar then\n> >>> something like\n> >>>\n> >>>       GIT_DIR=\"$(git rev-parse --path-format=absolute --git-dir)\" &&\n> >>>       GIT_COMMON_DIR=\"$(git rev-parse --path-format=absolute\n> >>> --git-common-dir)\" || exit\n> >>>       GIT_INDEX_FILE=\"$GIT_DIR/tmp-index-$$\"\n> >>>       export GIT_DIR GIT_COMMON_DIR GIT_INDEX_FILE\n> >>>       unset GIT_WORK_TREE\n> >>>       mkdir \"$output_directory\" && cd \"$output_directory\" &&\n> >>>       git read-tree -u \"$commit\"\n> >>>       status=$?\n> >>>       rm \"$GIT_INDEX_FILE\"\n> >>>       exit $status\n> >>>\n> >>> Which uses a temporary index file should work (note I haven't tested\n> >>> it). You may want to add \"--recurse-submodules\" and/or\n> >>> \"--no-sparse-checkout\" to the \"git read-tree\" commandline.\n> >>>\n> >>> Best Wishes\n> >>>\n> >>> Phillip\n> >>>\n> >>>> IMO all possible solutions are summarized in this thread\n> >>>> https://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export\n> >>>> I describe some of them with my remarks:\n> >>>>\n> >>>> - git checkout-index : works with HEAD only.\n> >>>> - git archive: influenced by export-ignore and export-subst\n> >>>> attributes, so may not produce exact copy of sources. (And needs tar).\n> >>>> - git worktree add -d : needs cleanup: git prune or git remove.\n> >>>> - git clone: Unfortunately, -b param cannot work with commit hash and\n> >>>> does not respect local worktree settings (e.g. autocrlf). So, a\n> >>>> solution may be a bit complicated: git clone -s -n . dest/path ; cp\n> >>>> .git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;\n> >>>> rm -rf .git\n> >>>> - git checkout: Unfortunately, modifies Git index, so some action to\n> >>>> revert index is necessary after: git --work-tree=/path/to/checkout/\n> >>>> checkout -f -q <tree-ish> -- ./\n> >>>>\n> >>>> For me, the best solution is with git clone, because it does not\n> >>>> modify Git index nor any source working tree settings, so no cleanup\n> >>>> is necessary. But it's a bit complicated, though. It seems to me that\n> >>>> \"git checkout\" could do this better and simpler if it would have some\n> >>>> param to not modify the Git index. Is it possible to enhance git\n> >>>> checkout? Or is there any other simple solution not mentioned in the\n> >>>> SO thread?\n> >>>>\n> >>>> Thank you\n> >>>> Ondra Medek\n> >>>>\n"}]}