Mercurial (aka
Hg ) is a very nice distributed version control system (distributed VCS). Among the conveniences of DVCS in general and Hg in particular, high flexibility can be emphasized. The repository can be called as you like, copied anywhere, commit to production on arbitrary chains (say, through QA or directly) and so on.
Well, more repositories can be nested. For example, your project consists of several smaller ones or includes third-party products. Module developers are more comfortable with working not with the whole project, but with its parts. In these cases, you can combine repositories.
If you put two repositories in one another, Mercurial will consider them in isolation. Commands addressed to the external repository do not apply to the nested. But how to manage a project if it is fragmented into isolated fragments - such bubbles, one in the other? Or, in other words, how can we see the forest (project) behind the trees (repositories) and work at its level?
ForestExtension will save us from the torment - an extension for Mercurial. This Forest adds several commands that are identical to the base but take into account the repository nesting.
')
Let's say we took home a large composite project, we fixed files in all modules and we want to push them back. The
fclone
(forest clone) team will copy to us the “forest” of the nested repositories (ie, the project), the
fstatus
(forest status) command will show the state of the entire “forest” (do we need to commit something?), And
fpush
(forest push) will push all modified files back, and will do it for the whole “forest” at once, i.e. we don't have to crawl through directories. In this case, “back” is the original, public “forest” of the project. If you also want to push changes from there to some third-party repositories, it’s enough to repeat the same
fpush
as part of the project - and that's it.
Create two repositories, each with a text file:
$ mkdir repo-one
$ cd repo-one
$ hg init
$ echo "hello" > hello.txt
$ hg ci -m"init one"
$ cd ..
$ mkdir repo-two
$ cd repo-two
$ hg init
$ echo "hello" > hello.txt
$ hg ci -m"init two"
$ cd ..
Copy the first repository inside the second:
$ hg clone repo-one repo-two/one
Do not forget that
repo-two / one is not part of
repo-two , it is simply embedded there.
And now Forest comes onto the scene. The
fclone
command
fclone
similar to the clone command, but, unlike it, does not ignore nested repositories.
$ hg fclone repo-two wc-two
We just made a local
repo-two replica, including
repo-two / one (
repo-one replica).
Let's make some changes to
repo-two / hello.txt and
repo-two / one / hello.txt (we will
lower listing).
Let's commit changes in each of the repositories separately (it is not hard to guess why the “forest” analogue of the
commit
command does not exist):
$ cd wc-two/ && ls
one hello.txt
$ hg ci -m"edited hello.txt"
$ cd one/
$ hg ci -m"edited hello.txt"
$ cd ..
Pushing the result back to
repo-two :
$ hg fpush
All, now
repo-two contains modified files
repo-two / hello.txt and
repo-two / one / hello.txt .
The next step may be pushing changes further, i.e. in
repo-one :
$ cd ../repo-two
$ hg fpush
Done; Now changes from
repo-two / one have passed to
repo-one . That's all.
Instead of
repo-two / one there may be a whole set of trees, and
fpush
process them all.
(The original topic is here: http://neithere.livejournal.com/381205.html )