Hi Ondra
On 13/05/2024 18:23, Ondra Medek wrote:
Hi Phillip,
besides dependency on tar, I do not want to use git-archive because
it's influenced by export-ignore and export-subst attributes, too (as
I have mentioned).
Thanks for git read-tree, seems it's exactly what I need. Just git
read-tree has complained that -u switch needs -m or --reset switches.
And I have simplified it to
Sorry I'd forgotten about that
git --work-tree="$destdir" read-tree --index-output="$destdir".git -u
--reset "$commit"
You should be aware that --reset will happily overwrite files in the
destination directory, using -m instead would stop existing files being
overwritten. If you change to -m you must set GIT_INDEX_FILE instead of
using --index-output otherwise only the files that differ from the
current index will be checked out. Also using a relative path for the
index file specified with --index-output or GIT_INDEX_FILE is error
prone when running the command from a subdirectory of the repository. I
avoided suggesting --work-tree because I wasn't sure how it handled
relative paths when run from a subdirectory but I think it is in fact ok.
rm -f "$destdir"/.git
May I post this solution to the SO thread I have mentioned?
That's entirely up to you but I'd make sure it works with relative paths
and note the difference between --reset and -m.
Best Wishes
Phillip
Thanks very much
Ondra
On Mon, 13 May 2024 at 17:28, Phillip Wood <phillip.wood123@xxxxxxxxx> wrote:
Hi Ondra
On 13/05/2024 08:26, Ondra Medek wrote:
Hello,
I need a simple script for unskilled users to do a fast checkout (LFS
friendly) of the current local Git clone at a certain commit to a
different directory I.e. something like "copy at a point in history".
I think using
git archive "$commit" --format=tar |
{ cd "$output_directory" && tar -xf -; }
is probably the simplest solution. If you don't want to rely on tar then
something like
GIT_DIR="$(git rev-parse --path-format=absolute --git-dir)" &&
GIT_COMMON_DIR="$(git rev-parse --path-format=absolute
--git-common-dir)" || exit
GIT_INDEX_FILE="$GIT_DIR/tmp-index-$$"
export GIT_DIR GIT_COMMON_DIR GIT_INDEX_FILE
unset GIT_WORK_TREE
mkdir "$output_directory" && cd "$output_directory" &&
git read-tree -u "$commit"
status=$?
rm "$GIT_INDEX_FILE"
exit $status
Which uses a temporary index file should work (note I haven't tested
it). You may want to add "--recurse-submodules" and/or
"--no-sparse-checkout" to the "git read-tree" commandline.
Best Wishes
Phillip
IMO all possible solutions are summarized in this thread
https://stackoverflow.com/questions/160608/do-a-git-export-like-svn-export
I describe some of them with my remarks:
- git checkout-index : works with HEAD only.
- git archive: influenced by export-ignore and export-subst
attributes, so may not produce exact copy of sources. (And needs tar).
- git worktree add -d : needs cleanup: git prune or git remove.
- git clone: Unfortunately, -b param cannot work with commit hash and
does not respect local worktree settings (e.g. autocrlf). So, a
solution may be a bit complicated: git clone -s -n . dest/path ; cp
.git/config dest/path/.git ; cd dest/path ; git co -q <commit-ish> ;
rm -rf .git
- git checkout: Unfortunately, modifies Git index, so some action to
revert index is necessary after: git --work-tree=/path/to/checkout/
checkout -f -q <tree-ish> -- ./
For me, the best solution is with git clone, because it does not
modify Git index nor any source working tree settings, so no cleanup
is necessary. But it's a bit complicated, though. It seems to me that
"git checkout" could do this better and simpler if it would have some
param to not modify the Git index. Is it possible to enhance git
checkout? Or is there any other simple solution not mentioned in the
SO thread?
Thank you
Ondra Medek