Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git worktrees in VSCode devcontainer

I would like to use VSCode devcontainers with Git worktrees. I'm following these instructions to get a directory layout where all branches I'm working on are side-by-side. It results in something like the following:

my-repo:
.
├── .bare
├── .git
├── main
└── feat-pytest-helpers

I can open the my-repo folder in VSCode and it will recognize the various worktrees right off the bat. Each of the branch folders has their own .devcontainer subfolder. However, VSCode won't offer to reopen in a devcontainer when I select a specific branch folder and I can see no way to "force" it to do so. The instructions here look relevant, but I think that then I won't be able to see the different different folders (branches) in the Explorer menu anymore.

In summary:

  • I would like to be able to open the my-repo folder with VSCode, so that I can see the subfolders and switch between them in the Explorer menu.
  • Trigger a rebuild&reopen in devcontainer whenever I switch between subfolders.

Is this at all possible? If not, are you aware of any workarounds?

like image 443
boberto Avatar asked Jun 08 '26 05:06

boberto


1 Answers

This requires mounting both the worktree and the git common dir ($(git rev-parse --git-common-dir)) on matching paths into the container. Which can be done by abusing docker-compose and init-command:

  1. Make a script, say .devcontainer/init.sh that will write the common directory to a file called .env: I am using:

    gitdir="$(git rev-parse --git-common-dir)"
    case $gitdir in
        /*) ;;
        *) gitdir=$PWD/$gitdir
    esac
    echo "GIT_REPO=$(realpath -s "$gitdir")" >> ".env"
    
  2. Use docker-compose to set up the container. In the docker-compose.yaml include:

    services:
      devcontainer:
        volumes:
          - ${GIT_REPO}:${GIT_REPO}:rw
    

    This abuses the fact that docker-compose will read file called .env in the same directory as the compose file and use the contained values for substitutions. That is the only way I found for getting values from an init command into the container.

  3. In devcontainer.json include settings

      "workspaceFolder": "${localWorkspaceFolder}"
    

    to make the workspace path inside match the path outside, and

      "initializeCommand": "sh .devcontainer/init.sh"
    

    to call that script before the container is created.

That should get you a working worktree.


  1. It would be nice if there was an official way to propagate values from the initializeCommand to the devcontainer.json itself, but unfortunately I didn't find any. This relies on a standard feature of docker compose, but that means you can't just use the normal "dockerfile"- or "image"-based configuration.

  2. Worse, the basic devcontainer tooling does not have any customization options at all, and VSCode only allows adding features, and only globally across all profiles. And you can't override the image specification with a feature.

So together this means as of this time you can't easily use container definitions provided by projects, but have to maintain your own modified versions. Which is why I'm considering switching to devbox instead (which sets up project-specific tools as addition to your environment without container and thus without blocking access to the git common dir, or your other tools you have installed outside the project).

like image 144
Jan Hudec Avatar answered Jun 10 '26 19:06

Jan Hudec