The FAQ, and hginit.com have been really useful for helping me make the transition from svn to hg.
However, when it comes to using Hg's subrepository feature in the manner of subversion's externals, I've tried everythign and cannot replicate the nice behavior of svn externals.
Here's the simplest example of what I want to do:
Init "lib" repository This repository is never to be used as a standalone; it's always included by main repositories, as a sub-repository.
Init one or more including repositories To keep the example simple, I'll "init" a repository called "main"
Have "main" include "lib" as a subrepository
Importantly -- AND HERE'S WHAT I CAN'T GET TO WORK: When I modify a file inside of "main/lib", and I push the modification, then that change gets pushed to the "lib" repository -- NOT to a copy inside of "main".
Command lines speak louder than words. I've tried so many variations on this theme, but here's the gist. If someone can reply, in command lines, I'll be forever grateful!
$ cd /home/moi/hgrepos ## Where I'm storing my hg repositories, on my main server
$ hg init lib
$ echo "foo" > lib/lib.txt
$ hg add lib
$ hg ci -A -m "Init lib" lib
$ cd /home/moi/hgrepos
$ hg init main
$ echo "foo" > main/main.txt
$ hg add main
$ cd main
$ hg clone ../lib lib
$ echo "lib=lib" > .hgsub
$ hg ci -A -m "Init main" .
This all works fine, but when I make a clone of the "main" repository, and make local modifications to files in "main/lib", and push them, the changes get pushed to "main/lib", NOT to "lib".
$ /home/moi/hg-test
$ hg clone ssh://[email protected]/hgrepos/lib lib
$ hg clone ssh://[email protected]/hgrepos/main main
$ cd main
$ echo foo >> lib/lib.txt
$ hg st
M lib.txt
$ hg com -m "Modified lib.txt, from inside the main repos" lib.txt
$ hg push
It shows that I've made a modification to a COPY of a file in lib, NOT to a file in the lib repository. If this were working as I'd like it to work, the push would be to hgrepos/lib, NOT to hgrepos/main/lib. I.e., I would see:
$ hg push
pushing to ssh://[email protected]/hgrepos/lib
Thank you in advance!
Emily in Portland
Simply right drag the file or folder from one working copy to where you want those to be included as externals. A context menu appears when you release the mouse button: SVN Add as externals here if you click on that context menu entry, the svn:externals property is automatically added.
Subrepositories is a feature that allows you to treat a collection of repositories as a group. This will allow you to clone, commit to, push, and pull projects and their associated libraries as a group. This feature was introduced in a preliminary form in Mercurial 1.3 and has been improved steadily since then.
Oops, sorry for the formatting in previous answer. Here it is again, formatted!
So, here are the two scenarios most folks will be faced with:
A) Using subrepositories in a completely local situation. This is Ryan's solution, essentially. I imagine only developers working solo will be in this boat.
cd /home/moi/hgrepos
hg init lib
cd lib
echo foo > lib.txt
hg ci -A -m Init
cd /home/moi/hgrepos
hg init main
cd main
echo foo > main.txt
echo lib = ../lib > .hgsub
hg clone ../lib
hg add .hgsub main.txt
hg ci -m Init
cd /home/moi/hgrepos
hg clone main main-clone
cd main-clone/lib
echo "Modified while on main trunk" >>lib.txt
hg commit -m "Modified lib.txt, while on main trunk"
hg push
cd /home/moi/hgrepos/lib
hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
cat lib.txt
foo
Modified while on main trunk
B) Using subrepositories over ssh.
I imagine most developers working on teams will be in this boat.
1) Set up lib
cd /home/moi/hgrepos
hg init lib
cd lib
echo foo > lib.txt
hg ci -A -m Init
2) Set up main
cd /home/moi/hgrepos
hg init main
cd main
echo foo > main.txt
echo lib=ssh://[email protected]/hgrepos/lib > .hgsub
hg clone ssh://[email protected]/hgrepos/lib lib
hg add .hgsub main.txt
hg ci -m Init
3) Clone lib to hgtest dir
cd /home/moi/hgtest
hg clone ssh://[email protected]/hgrepos/lib lib
4) Clone main to hgtest dir
cd /home/moi/hgtest
hg clone ssh://[email protected]/hgrepos/main main
5) Modify lib.txt while on main trunk
cd /home/moi/hgtest/main/lib
echo "Modified while on main trunk" >>lib.txt
hg commit -m "Modified lib.txt, while on main trunk"
hg push
6) Verify that lib.txt got changed in the lib repository
cd /home/moi/hgtest/lib
hg pull
hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
cat lib.txt
foo
Modified while on main trunk
The problem is with your .hgsub file. It points to where the lib repo is, so if lib is a sibling to main it should be:
lib=../lib
Also your hg add lib
and hg add main
lines don't make sense. To what repo outside of main and lib are those being added? You're running them while in in /home/moi/hgrepos
.
Here's your script with some tweaks:
+ cd /home/ry4an/hgtest
+ hg init lib
+ echo foo
+ cd lib
+ hg commit -A -m Init lib
adding lib.txt
+ cd /home/ry4an/hgtest
+ hg init main
+ echo foo
+ cd main
+ echo lib=../lib
+ hg clone ../lib
destination directory: lib
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ hg add .hgsub main.txt
+ hg commit -m Init main: initial file and a .hgsub
committing subrepository lib
+ cd /home/ry4an/hgtest
+ hg clone main main-clone
updating to branch default
pulling subrepo lib
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ cd main-clone
+ echo foo
+ hg commit -m Modified lib.txt, from inside the main repos
committing subrepository lib
+ hg push
pushing to /home/ry4an/hgtest/main
pushing subrepo lib
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
To do that over ssh:// you need only make a single change. When cloning the main repo change hg clone main main-clone
to hg clone ssh://host/hgtest/main main-clone
-- cloning the main automatically clones the lib -- that's the subrepo benefit.
Here's a log of that working:
+ cd /home/ry4an/hgtest
+ hg init lib
+ echo foo
+ cd lib
+ hg commit -A -m Init lib
adding lib.txt
+ cd /home/ry4an/hgtest
+ hg init main
+ echo foo
+ cd main
+ echo lib=../lib
+ hg clone ../lib
destination directory: lib
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ hg add .hgsub main.txt
+ hg commit -m Init main: initial file and a .hgsub
committing subrepository lib
+ cd /home/ry4an/hgtest
+ hg clone ssh://localhost/hgtest/main main-clone
The authenticity of host 'localhost (::1)' can't be established.
RSA key fingerprint is 0c:58:d6:d3:d3:16:14:ee:3b:be:01:bc:c7:3c:92:0b.
Are you sure you want to continue connecting (yes/no)? yes
ry4an@localhost's password:
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 3 changes to 3 files
updating to branch default
pulling subrepo lib
ry4an@localhost's password:
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
remote: Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
+ cd main-clone
+ echo foo
+ hg commit -m Modified lib.txt, from inside the main repos
committing subrepository lib
+ hg push
ry4an@localhost's password:
pushing to ssh://localhost/hgtest/main
pushing subrepo lib
ry4an@localhost's password:
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With