Boost logo

Boost :

Subject: Re: [boost] [git] Mercurial?
From: Martin Geisler (mg_at_[hidden])
Date: 2012-03-26 01:48:53

Joel de Guzman <joel_at_[hidden]> writes:

> Wanting to make it modular, I searched around and found git
> filter-branch. Hence, I was able to create a modular Spirit-3 branch
> without the other boost libraries. All is well until I did a
> downstream merge to track the changes that's going into the Boost
> trunk into my Spirit-3 branch.
> boost-trunk (pull)--> spirit3
> And hah! It pulls in everything (all boost libraries) again.
> So, how do you do what I intend to do? All I want is to have this repo
> structure:
> spirit3
> boost/spirit
> libs/spirit
> that can do a merge both ways (upstream and downstream to and from the
> boost trunk); needless to say, with all the histories intact.
> With SVN, it is very easy to extract sub-directories while still
> tracking changes both ways to and from the source. In Git, everything
> seems to be one whole global repository. This is one thing I dislike
> and which SVN has better control over: modularity. Sure, you can make
> many "modular" git repositories instead of one big one like boost. But
> the reality is, you don't predict up front how a library is
> modularized. Spirit itself spawned at least 3 libraries (Phoenix Wave
> Fusion) that stand on their own now. At one point, in the life of a
> library, you may want to refactor and decouple parts somewhere else.
> Doing this in Git is not straightforward at all, unless I am missing
> something obviously simple (?).

I'm pretty sure you're not missing anything -- Git/Mercurial want you to
operate on the entire repository.

> I'd love to hear from the Mercurial experts as well.

You can split a Git or Mercurial repository into two new repositories
and extract a sub-tree but you're rewriting history when you do it.
Rewriting history implies getting new SHA-1 hash values for the
changesets (since their content changes) and so you get *new* and
unrelated repositories out of this.

I agree with you that SVN is easier to work with here since you can
checkout subtrees if you want. You can just toss everything into a
single company-wide repository and it will work fine.

However, in practice, it doesn't seem to be a big problem. One common
solution is to just rename things at some point if you decide to split a

  cd your-big-repo
  hg remove x-dir y-dir
  hg rename z-dir/* .
  hg commit -m "We now focus on z-dir only"

You still have the history for the x-dir and y-dir, but the files from
z-dir are now at the top-level of the repository. Because you only
renamed the files, you can still push/pull from other clones that have
the x-dir and y-dir files.

If you want to re-write history you enable the standard convert
extension with

  convert =

in your ~/.hgrc file, create a filemap.txt file with

  include z-dir
  rename z-dir .

and run

  hg convert --filemap filemap.txt your-big-repo your-z-repo

That's the equivalent of Git's filter branch.

Martin Geisler
Mercurial links:

Boost list run by bdawes at, gregod at, cpdaniel at, john at