Fossil User Forum

Using Branches With Different File Trees
Login

Using Branches With Different File Trees

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.