VCS comparison table
torvalds at osdl.org
Sun Oct 22 18:12:00 BST 2006
On Sun, 22 Oct 2006, Tim Webster wrote:
> On 10/22/06, Linus Torvalds <torvalds at osdl.org> wrote:
> > > project/file-1
> > > project/file-2
> > > project/.git-1
> > > project/.git-2
> > Ok, that's just insane.
> > Anyway. Git certainly allows you to do some really insane things. The
> > above is just the beginning - it's not even talking about alternate object
> > directories where you can share databases _partially_ between two
> > otherwise totally independent repositories etc.
> Perhaps this is insane, but it does not make sense to track all config
> files in etc as though they belong in a single repo.
Oh, ok, now I see what you're going after.
Right - if you track system directories in a repo, you'd quite possibly
end up with multiple repositories. Although even then, I'd actually
suggest that as a git user, you would only have one actual repository, and
just multiple branches that have a disjoint set of files (again, it's
certainly possible to have file overlap too, of course).
But the usage I would seriously suggest is to _not_ do development "inside
/etc" itself. You'd have those git repositories somewhere else, say in
"/usr/src/etc-repo" or similar, and then you'd have a few extra wrappers
to help your particular usage. I have a few reasons for this:
- I think being in /etc and doing development is just fundamentally scary
in itself, because if you do something wrong in the current directory,
you're just pretty badly off. It's better to have a "buffer zone" that
you do development in, and when you're happy, you do a "install"
command or something.
- I think developing as "root" is totally broken, and some of the files
you are tracking may not even be _readable_ to normal users in their
real form, so you can't even do trivial things like "diff" as a normal
user otherwise. So again, the solution to this would be to do
development somewhere else, and have specific wrappers (with "sudo" as
appropriate, and your developer ID obviously specially in the sudo
files) to do those special "realdiff" and "install" commands.
- finally: when you work with almost any SCM designed for source control,
you're almost inevitably going to have to have some "special" way to
track the things that source control usually does _not_ track because
it makes no sense for source code. So you'd have to have some special
file that tracks ownership/group/full permissions information, and
perhaps special devices (if you're tracking things like /dev).
Again, the way to solve this would tend to be to have a few helper
scripts that use regular file-contents that _describe_ these things to
do "realdiff" and "install".
In other words, for at least three _totally_ different reasons, you really
don't want to do tracking/development directly in /etc, but you want to
have a buffer zone to do it. And once you have that, you might as well do
_that_ as the repository, and just add a few specialty commands (let's
call them "plugins" to make everybody happy) to do the special things.
And once you have that kind of setup, you're really better off with
more of a "several branches for different kinds of files" or even totally
different repositories. That's a detail, and I don't think anybody really
Anyway, to make this slightly more grounded in examples, let me give a
quick overview of what I'd do if I did this with git. Not a "real" setup
at all, but kind of a "maybe something like this" - so don't get _too_
hung up about the details, ok? It's just a rough draft kind of thing.
First off, let's just say that I want to track /etc/group, /etc/passwd and
/etc/shadow as one "thing". Whether that thing is a repository of its own
or a branch in a bigger repository doesn't matter (right now I'm only
doing those three), and quite frankly, I'm not going to even go into
whether it _really_ makes sense to track "groups" and the passwd files
together, but it's just an example, ok?
What I'd do is roughly:
# set up the new repo (or branch, or..)
# copy the data, set up a PERMISSIONS file to track extra info
sudo cp /etc/group /etc/passwd /etc/shadow .
sudo chown user:user *
cat <<EOF > PERMISSIONS
group root:root 0644
passwd root:root 0644
shadow root:root 0400
git add .
git commit -m "Initial setup"
and now I have the initial setup, together with permissions and user/group
information on the things, all ready to track. I can do development in
this as if it was a normal source-code repository.
So now I can do "work work work commit commit commit" as if these files
were nothign special. What else do I need? I need the "plugins" to
actually expose (install) my work, and perhaps to check that /etc matches
what I expect (and nobody else did anything behind my back that I'd need
Let's call them "install" and "realdiff" as I did above, ok?
And again, I'm not going to even claim that the above two "plugins" are
the right ones (maybe you want other operations too to interact with the
"real" installed files), and I'm not going to really get all the details
right, but here's kind of how you _might_ do it.
To create the script (let's make it shell, because that's what I'm used
to, but it could be anything) "git-install" in your git binary directory,
and make it do something like this:
while read name chown chmod
cp $name $name.tmp &&
sudo chown $chown $name.tmp &&
sudo chmod $chmod $name.tmp &&
sudo mv $name.tmp /etc/$name
done < PERMISSIONS
and make it executable.
Now, you can work in your git directory, and when you're happy, you can do
to actually copy it into the _real_ directory in /etc.
See? You can do something similar for "realdiff", that would compare the
contents in /etc with what you have now in your development tree (where
you want to script the thing to compare the PERMISSIONS file too).
And note: if you do the "plugin scripts" properly, they can work for _all_
your repositories that track different files in /etc. So you can work in
many different repos, and track different files in each, and "git install"
will do the right thing for each, regardless of the actual files you're
Doesn't this sound like a workable situation? You get all the normal SCM
tools (looking at history etc), and there's only a few special things you
need to do when you actually want to install a specific version.
Btw: none of this is really "git-specific". The above tells you how to do
local "git plugins", and it's obviously fairly trivial, but I suspect any
SCM can be used in this manner.
More information about the bazaar