Re: Strange checkout with GIT_WORK_TREE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2022-01-21 at 16:37:58, Lauri Rooden wrote:
> Does the GIT_WORK_TREE get lost on the middle of process
> or I am misunderstand the git checkout?
> 
> What did you do before the bug happened? (Steps to reproduce your issue)
> - I wrote a shell script to reproduce
> 
> ```git-test.sh
> GIT_ROOT=$(mktemp -d)
> GIT_COPY=$(mktemp -d)
> 
> echo "Create git repo with two commits: $GIT_ROOT"
> cd $GIT_ROOT
> git init
> echo 1 > a.txt
> echo 1 > b.txt
> git add *.txt
> git commit -m "Initial commit"
> echo 2 > b.txt
> git add b.txt
> git commit -m "Second commit"
> 
> echo "Checkout to other work-tree: $GIT_COPY"
> GIT_WORK_TREE=$GIT_COPY git checkout HEAD~1
> git status
> 
> echo "ORIGIN $GIT_ROOT"
> ls -la $GIT_ROOT
> echo "COPY $GIT_COPY"
> ls -la $GIT_COPY
> ```
> 
> What did you expect to happen? (Expected behavior)
> - a.txt and b.txt checkouted to $GIT_COPY both with content `1`
> - current folder unchanged
> 
> What happened instead? (Actual behavior)
> - only b.txt checkouted to $GIT_COPY
> - HEAD~1 checkouted in current folder but folder content remains HEAD

Here's what I believe is happening here.  When you run "git checkout
HEAD~1", Git notices that the only file that's stale in the index
compared to what's already present is b.txt; a.txt is up to date.  As
such, it only writes one file into the working tree, since only one file
needs to be updated.  This is an optimization, since for large working
trees, writing out every file every time would be extremely expensive.

I don't know what our official position is on switching working trees
like this. I would generally recommend you pick one and stick to it, but
if you want to do this, you'll need to update the index for the working
tree first.  You can do that by something like this in place of your
checkout:

  GIT_WORK_TREE=$GIT_COPY git update-index --refresh
  GIT_WORK_TREE=$GIT_COPY git checkout -f HEAD~1

That will inform Git that your working copy is stale and then the -f
flag to checkout will force Git to overwrite the missing files.

If your goal is to have multiple worktrees for one repository, you can
do that with "git worktree", which will keep separate indices for your
separate directories, provided they're on separate branches.  If you
just want to create a detached copy of the files for a repository from a
commit, you can do this:

  git archive HEAD~1 | tar -C "$GIT_COPY" -xf -

Hopefully that explains what's going on.  If you tell us a little bit
more about what you wanted to accomplish, we may be able to help you
find a way to do it that provides results that are at least less
surprising and more predictable.
-- 
brian m. carlson (he/him or they/them)
Toronto, Ontario, CA

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux