Using Branches With Different File Trees
(1) By Dave St.Germain (davestg) on 2024-05-23 12:38:17 [link] [source]
Is anyone else using branches with unrelated file trees? I know it's technically possible, but somehow it seems a little bit odd or potentially confusing.
For instance, I have a repository for configuration files. There's a branch for the MacOS config files, and a branch for the Linux configuration files, etc. There might be some similar directory layout between them, but otherwise they're completely independent. This way, I can clone the repository on each machine and checkout the correct branch for the OS.
Another more controversial example might be if you had a large project with extensive documentation, and you split the documentation into its own branch. If there were contributors who only worked on docs, they'd checkout the docs branch and not have to see any of the code.
Does this seem like a clever solution, or a recipe for problems? One reason it seems unsupported is that the file browser in the UI doesn't have a pulldown for changing the branch (you can alter the URL, of course), and the other views -- "Files in the top-level directory in any check-in" -- would be confusing if the branches were supposed to be completely separate directory trees.
Thoughts?
(2) By spindrift on 2024-05-23 13:27:20 in reply to 1 [link] [source]
I guess the question is "why not just use different repos"?
If it's just you, it doesn't really matter - whatever floats your boat (and you can have multiple checkouts on disk at any one time on different branches).
If it's a group effort, you lose all the ability to set different levels of access and privileges, and have the disadvantages of isolated code structures without the benefits of independent management and availability of the same.
So I have no doubt that you can do as you suggest. But I can't think of a good enough reason as to why you would choose to, unless you were desperate for a monolithic repository archive while maintaining parallel hierarchies.
In which case, go for it.
(3.1) By Warren Young (wyoung) on 2024-05-23 13:34:23 edited from 3.0 in reply to 1 [source]
I know it's technically possible
It's not merely technically possible to have two branches that share nothing but a common initial checkin, a single Fossil repo can support multiple wholly independent DAGs, lacking even a common root.
But since "technically possible" and "good idea" are not the same thing, it will take some convincing before I'll be willing to show you how that can be done. 🤓
they're completely independent
Then per my recent post I will tell you that they should live in separate repos. I see zero practical value in having these two sets of files committed to the same repo, and multiple reasons not to. The other thread goes into the reasons sufficiently well that I will refrain from repeating them here.
The closest thing I have to your situation is my ~/bin
repo, which does have a trunk branch for the portable, POSIX-compliant version of my scripts expected to run on Linux at least, then a macOS branch for scripts that either never can reasonably work on anything else or to hold the deltas needed to patch up the differences relative to trunk so that my scripts don't have to contain redundant platform testing logic.
The next-closest repo I have to your situation is the one holding ~/.ssh/config
rules and keys that I want replicated on multiple machines. This is portable, though, not needing Linux vs macOS branches.
It brings me to my next point, though, which is that using Fossil to manage whole-system config archives is generally a bad idea. Not only is there the portability and lack of a common base aspect you bring up, Fossil doesn't track file permissions beyond the EXECUTE bit. The only reason I find my ~/.ssh
repo tolerable is that OpenSSH checks permissions on startup and refuses to use the new files until I chmod 600 them. Few other services will do that.
contributors who only worked on docs, they'd checkout the docs branch and not have to see any of the code.
Is it "have to" or "should be able to"?
If the doc writers have no business changing the code — or possibly even seeing it — then you need separate repos for the simple reason that each new repo gives you a separate RBAC system. The SQLite project does this, for one.
the file browser in the UI doesn't have a pulldown for changing the branch
A mitigating factor is that if you don't select any branch, the file browser shows the union of all files, regardless of where and when they exist in the DAG.
(4) By Dave St.Germain (davestg) on 2024-05-23 13:54:09 in reply to 3.1 [link] [source]
But since "technically possible" and "good idea" are not the same thing, it will take some convincing before I'll be willing to show you how that can be done.
There's another example I brought up earlier -- using fossil to track changes to town bylaws. In that repo, I am keeping the trunk branch clean, showing only the bylaw changes. But I also wanted a place for documentation about the project, and possibly to add source code that I used to build the site. I stuck that in another branch of the same repository, so that the information could be available at /doc/<branch>/about.md
(or whatever). I think the convenience of having it all in one repository outweighs the potential confusion.
I see zero practical value in having these two sets of files committed to the same repo, and multiple reasons not to.
I shouldn't have said completely independent. For my config file repo (for home directory dotfiles), there's a trunk branch with common files, and separate branches for each OS. It's possible that one of the OS branches will diverge entirely, and it's possible that I'll add more "common" files to the trunk, and merge them to the branches.
In that example, it's just me dealing with the changes, so this arrangement seems perfectly fine.
It brings me to my next point, though, which is that using Fossil to manage whole-system config archives is generally a bad idea.
Yes, I have another repo for /etc/ config files. That one has a shell script that runs install
to copy each file into /etc/, with the correct permissions. It's much safer than symlinking...
If the doc writers have no business changing the code — or possibly even seeing it — then you need separate repos
That's a good point. Actually, I have yet to use fossil in a team environment, so I'm not sure what sort of permission issues would arise.
(5) By Andy Bradford (andybradford) on 2024-05-23 14:38:57 in reply to 1 [link] [source]
> Does this seem like a clever solution, or a recipe for problems? Seems like it could potentially be a source of problems. If I understand correctly, there exists a directory structure like: configs/abc.conf configs/xyz.conf configs/foo.conf configs/bar.conf docs/branch.docx docs/howto.tex And if I checkout a branch named "macos" I get a different set of those files (and even the same files but different contents) than I get when I checkout "linux"? But then if I checkout "documentation" I only see the docs directory? How do you prevent people from merging the branches? Why should contributors who only work on docs not "see" the other files? How do you prevent people from accidentally checking out the wrong files and accidentally working on them (remember that in this arrangement a branch represents a "unique" set of files)? I suppose this can be done as long as people all agree and are "trained", but it's kind of odd. A better separation would be at the repository level, or even at the directory level: macos/configs/abc.conf macos/configs/foo.conf linux/configs/bar.conf linux/configs/xyz.conf docs/branch.docx docs/howto.tex Or at the repository level you would just have one repository for each "concern" and then you only clone the correct "concern" on the various OS: fossil clone ssh://server/macos.fossil fossil clone ssh://server/linux.fossil fossil clone ssh://server/documentation.fossil Speaking of "controversial examples", a more controversial option would be to have independent DAGs in a single Fossil repository (e.g. have separate timelines which isolate commits), however, Fossil makes it more difficult to work with such a repository than in the past. (e.g. it warns you when you try to commit that a branch already exists by the same name and needs "force", it warns you if you have multiple trunks even if there is no relationship between the trunks because they are on separate DAGs). However, if you're intention is to have separate branches anyway, you could avoid those stumbling blocks and do something like: fossil new masterproject.fossil mkdir master cd master fossil open --empty ../masterproject.fossil fossil add configs/abc.conf configs/foo.conf fossil commit --branch macos -m "initial commit for macos" fossil close fossil open --force --empty ../masterproject.fossil fossil add configs/bar.conf configs/xyz.conf fossil commit --branch linux -m "initial commit for linux" fossil close fossil open --force --empty ../masterproject.fossil fossil add docs/* fossil commit --branch docs -m "initial commit for docs" By the way, this example still suffers from the same complications that your original proposal does, and may actually introduce other difficulties so I don't recommend it unless you're prepared to be responsible for the consequences. For example, you may see things like: $ fossil update macos ADD configs/abc.conf - overwrites an unmanaged file, original copy backed up locally ADD configs/foo.conf - overwrites an unmanaged file, original copy backed up locally REMOVE docs/branch.docx REMOVE docs/howto.tex ... WARNING: 2 unmanaged files were overwritten "fossil undo" is available to undo changes to the working checkout. That might be "scary", it might not, to those who work with multiple branches. In fact, you may now realize that you need to train yourself to know when you should use "fossil update" when switching between the different branches that might exist, and when instead you should use "fossil checkout". At any rate, a lot of how the files are organized into Fossil repositories depends on the relationship between the files. Depending on what you're trying to accomplish, it seems like it might be better to separate the concerns into different directories in a single repository, than trying to separate the concerns through branches in Fossil. But you're more than welcome to try if it makes sense to you. It would be interesting to know how it works out. Andy
(6) By Dave St.Germain (davestg) on 2024-05-23 15:08:06 in reply to 5 [link] [source]
And if I checkout a branch named "macos" I get a different set of those files (and even the same files but different contents) than I get when I checkout "linux"? But then if I checkout "documentation" I only see the docs directory?
Actually, that's mixing up the two examples I gave.
Example 1 is the repo I use for dot files:
.bashrc
.profile
.tmux.conf
.vimrc
.config/whatever
There's a branch for macos and a branch for openbsd, linux, etc. The openbsd branch might not have .bashrc, and it'll have other stuff. Trunk has a few common files between them.
I just fossil up mac
and not worry about other OS files cluttering the working tree. And I'm the only person managing it.
Example 2 was a hypothetical scenario where you have source code on trunk and documentation on a doc
branch. That way, people who work on documentation would never accidentally commit something to trunk
, because the working tree would make it obvious which branch they're on. I'd imagine it might be useful if you have a large amount of documentation, or a lot of churn, but you want to package it all for easy reference on the website. I don't know; maybe nobody would do that.
Yes, there could be permission issues. It's the same problem that any fossil project might have – committers can commit to any branch. How do you prevent a "developer" account from clobbering trunk? With fossil, it's left to the social realm.
Depending on what you're trying to accomplish, it seems like it might be better to separate the concerns into different directories in a single repository, than trying to separate the concerns through branches in Fossil.
In a previous iteration of my "/etc configuration repo", I used separate directories for each machine. But I was using mercurial, and I don't think it's possible (or at least not obvious) how to have separate file trees per branch (changes are tracked per file, not per tree). With fossil, it's dead simple.