Mercurial suprepositories

2.2k views Asked by At

I have got a question regarding suprepositories. Our project is set up like this:

+ projectA
    + some files
    + dependencyA
        + some files

dependencyA is a subrepository. It was created this way:

  1. cd projectA
  2. mkdir dependencyA
  3. cd dependencyA
  4. hg init
  5. hg pull ssh://hg@somerandomiphere/dependencyA
  6. cd ..
  7. echo dependencyA = ssh://hg@somerandomiphere/dependencyA > .hgsub
  8. hg add
  9. hg commit
  10. hg push

If I make changes to the suprepository, then commit and push them from main project. Both of them will be pushed to the server since its recursive. Now my colleague wants to pull changes from the server. But since nothing was changed in the main project, it wont work. But if I change something in the main project and push it to server. Upon hg pull he will get the newest changeset and if he does hg update then, it will update the subrepository as well. This is expected behaviour.

Now my question would be, if there is a way to pull changes, but only for subrepository without making a new clone of it or what would be the best way to do it.

2

There are 2 answers

1
realshadow On BEST ANSWER

What was suggested above works like I thought it would. The real problem was my way of creating a subrepository.

Instead of:

  1. cd projectA
  2. mkdir
  3. dependencyA
  4. cd dependencyA
  5. hg init
  6. hg pull ssh://hg@somerandomiphere/dependencyA

It should have been a simple:

  1. hg clone ssh://hg@somerandomiphere/dependencyA dependencyA

As we know .hgsusbtate will lock the subrepo on specific revision after commit. This is what happened, but (!) doing hg pull in subrepository ended with an error

paths cannot contain dot file components

So this means my subrepo was locked on the revision it was updated after commit and it could not pull changes from its repository due to the error shown above. Why this happened is explained pretty well in this accepted answer.

Solution:

cloning is the way to go

5
Lazy Badger On

Subrepository in Mercurial wiki, p. 2.5 "Pull"

The 'pull' command is by default not recursive. This is because Mercurial won't know which subrepos are required until an update to a specific changeset is requested. The update will pull the requested subrepositories and changesets on demand. To get pull and update in one step, use 'pull --update'.

Note that this matches exactly how 'pull' works without subrepositories, considering that subrepositories lives in the working directory:

  • 'hg pull' gives you the upstream changesets but doesn't affect your working directory.
  • 'hg update' updates the contents of your working directory (both in the top repo and in all subrepos)

It might be a good idea to always pull with --update if you have any subrepositories. That will generally ensure that updates not will miss any changesets and that update thus not will cause any pulls. If the pull with update fails due to crossing branches then 'hg update' must be used to get all the subrepository updates.