git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Multiple working trees with GIT ?

From
Willy Tarreau <w@1wt.eu>
Date
Jan 24, 2008, 07:49 UTC
Message-ID
<20080124074952.GA8793@1wt.eu>
Hi all,

I'm having long thoughts about how to use GIT to manage a distro. One of the aspects which comes very often is the notion of "variant" for a packaging. For instance, the whole project could consist in a list of packages with their branches, but this list may vary depending on the platform, the medium, etc... I was searching how to propagate common changes withing variants with the least hassle.

I figured out that having one file list per variant will be very annoying. In another project, that's already what I have and frankly, applying the same change to 10 files is counter-productive. Since the lists will often be the sames except for a few entries, and since most updates will be relevant to all variants, I thought branches will be my best friends.

But I would like to be able to always access file lists, without having to constantly git-checkout <variant-X>.

Finally, I found a very convenient solution, but I don't know if there are any risks using it. If we can conclude to a riskless usage (with/without some adjustments), I can contribute a script to setup this environment.

The idea is to have multiple working trees in a subdirectory of the normal one. Some would probably like them to be movable anywhere else, but let's not complicate things first. But in order not to constantly have to pull/push in every tree, I set up the .git repo of each working tree with many symlinks :

  project/
          .git/ (normal repo)
          ... master checked out there by default ...
          worktree/
                   variant_a/
                             .git/ (symlinks)
                   variant_b/
                             .git/ (symlinks)
                   variant_c/
                             .git/ (symlinks)
Each variant is set up like this :
    4096 Jan 24 08:44 .git
      19 Jan 24 08:27 .git/HEAD
      28 Jan 24 08:30 .git/logs
     419 Jan 24 08:44 .git/logs/HEAD
      26 Jan 24 08:31 .git/logs/refs -> ../../../../.git/logs/refs
      18 Jan 24 08:31 .git/refs -> ../../../.git/refs
      21 Jan 24 08:31 .git/objects -> ../../../.git/objects
      18 Jan 24 08:31 .git/info -> ../../../.git/info
      19 Jan 24 08:31 .git/hooks -> ../../../.git/hooks
      25 Jan 24 08:31 .git/description -> ../../../.git/description
      20 Jan 24 08:31 .git/config -> ../../../.git/config
     118 Jan 24 08:44 .git/index
      22 Jan 24 08:31 .git/branches -> ../../../.git/branches
      63 Jan 24 08:44 .git/FETCH_HEAD
      41 Jan 24 08:44 .git/ORIG_HEAD

In fact, I found that each directory which hosts a HEAD file needs to remain a directory because of this head, but all other dirs can be symlinks to original tree.

This works pretty well. I can simply cd worktree/variant_a and work on a file, or pull master, or even git-cherry-pick from other branches (pretty convenient for this usage). But I don't know what caveats I may encounter.

Maybe there are other solutions too. I see that we tend to replace symlinks everywhere with ref files. We might as well (in a far future version) accept a file for ".git" which would contain a path to the central repo and the branch's head.

I'm open to comments. Please keep me CC, I'm not subscribed to the git list.

Thanks, Willy

Next: Julian Phillips
Message 1 of 8 in “Multiple working trees with GIT ?”
  1. Willy TarreauJan 24, 2008
  2. Julian PhillipsJan 24, 2008
  3. Johannes SchindelinJan 24, 2008
  4. Willy TarreauJan 24, 2008
  5. Johannes SchindelinJan 24, 2008
  6. Willy TarreauJan 24, 2008
  7. Willy TarreauJan 24, 2008
  8. J. Bruce FieldsJan 24, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.