moby / buildkit

concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit
https://github.com/moby/moby/issues/34227
Apache License 2.0
8.14k stars 1.15k forks source link

branch/tag confusion with Git checkout using `--keep-git-dir` #4557

Open jedevc opened 9 months ago

jedevc commented 9 months ago

Given the following Dockerfile:

FROM alpine

RUN apk add git tree

# note that v0.12.4 is ambiguous
ADD --keep-git-dir=true https://github.com/moby/buildkit.git#v0.12.4 /repo
WORKDIR /repo
RUN git tag -l
RUN git branch -v
RUN git status
RUN tree .git/refs

We get the following output on a build:

#6 git://github.com/moby/buildkit.git#v0.12.4
#6 0.050 Initialized empty Git repository in /var/lib/buildkit/runc-overlayfs/snapshots/snapshots/3/fs/
#6 2.204 833949d0f7908608b00ab6b93b8f92bdb147fcca   refs/tags/v0.12.4
#6 ...

...

#6 git://github.com/moby/buildkit.git#v0.12.4
#6 6.497 From https://github.com/moby/buildkit
#6 6.497  * [new tag]         v0.12.4    -> v0.12.4
#6 6.525 Initialized empty Git repository in /var/lib/buildkit/runc-overlayfs/snapshots/snapshots/6/fs/.git/
#6 6.529 commit
#6 6.950 From file:///var/lib/buildkit/runc-overlayfs/snapshots/snapshots/3/fs
#6 6.950  * [new tag]         v0.12.4    -> v0.12.4
#6 6.950  * [new tag]         v0.12.4    -> v0.12.4
#6 7.274 Note: switching to 'FETCH_HEAD'.
#6 7.274 
#6 7.274 You are in 'detached HEAD' state. You can look around, make experimental
#6 7.274 changes and commit them, and you can discard any commits you make in this
#6 7.274 state without impacting any branches by switching back to a branch.
#6 7.274 
#6 7.274 If you want to create a new branch to retain commits you create, you may
#6 7.274 do so (now or later) by using -c with the switch command. Example:
#6 7.274 
#6 7.274   git switch -c <new-branch-name>
#6 7.274 
#6 7.274 Or undo this operation with:
#6 7.274 
#6 7.274   git switch -
#6 7.274 
#6 7.274 Turn off this advice by setting config variable advice.detachedHead to false
#6 7.274 
#6 7.274 HEAD is now at 833949d Merge pull request #4452 from crazy-max/v0.12.4_cherry-picks
#6 DONE 9.5s

#8 [3/7] ADD --keep-git-dir=true https://github.com/moby/buildkit.git#v0.12.4 /repo
#8 DONE 0.4s

#9 [4/7] WORKDIR /repo
#9 DONE 0.1s

#10 [5/7] RUN git tag -l
#10 0.108 v0.12.4
#10 DONE 0.1s

#11 [6/7] RUN git branch -v
#11 0.097 * (no branch) 833949d Merge pull request #4452 from crazy-max/v0.12.4_cherry-picks
#11 0.097   v0.12.4     833949d Merge pull request #4452 from crazy-max/v0.12.4_cherry-picks
#11 DONE 0.1s

#12 [7/7] RUN git status
#12 0.288 Not currently on any branch.
#12 0.288 nothing to commit, working tree clean
#12 DONE 0.3s

#13 [8/8] RUN tree .git/refs
#13 0.134 .git/refs
#13 0.134 ├── heads
#13 0.134 │   └── v0.12.4
#13 0.134 └── tags
#13 0.134     └── v0.12.4
#13 0.134 
#13 0.134 3 directories, 2 files
#13 DONE 0.2s

Note that we clone v0.12.4, a tag in the https://github.com/moby/buildkit repository. However, we can see that a branch v0.12.4 has also been created, in addition to a tag. Ideally, we shouldn't do this, since this makes it an ambiguous ref.

Observed against buildkit version v0.12.4 and master.

Related:

jedevc commented 9 months ago

Did a brief investigation (will probably return at some point), but this seems related to https://github.com/moby/buildkit/blob/a09112603a36532b8e44ade74ee3fd8383f4b708/source/git/source.go#L561

If I change this line to pullref += ":refs/remotes/origin/" + pullref then instead of the output:

#6 6.950 From file:///var/lib/buildkit/runc-overlayfs/snapshots/snapshots/3/fs
#6 6.950  * [new tag]         v0.12.4    -> v0.12.4
#6 6.950  * [new tag]         v0.12.4    -> v0.12.4

I get:

#6 2.739 From file:///var/lib/buildkit/runc-overlayfs/snapshots/snapshots/3/fs
#6 2.739  * [new tag]         v0.12.4    -> origin/v0.12.4
#6 2.739  * [new tag]         v0.12.4    -> v0.12.4

And then only get the tag, and not the branch as well. But I'm not familiar enough with the refspec syntax to immediately identify why this is.