title: Mercurial workflow for subrepos to avoid "Can't merge due to uncommitted changes"
body: <p>When working with a Mercurial repository ("outer") that has a subrepository ("inner"), often you can end up with the problem whereby you're trying to do a merge on the outer but it fails due to "uncommitted changes" when no changes are apparent (<code>hg st</code> for the outer shows no changes). </p>
  
  <p>The problem is down to the subrepository state: the <code>.hgsubstate</code> file contains a changeset ID for the subrepo which is actually different to the subrepo working copy changeset (or, trivially, there is an uncommitted change in the subrepo).</p>
  
  <p>I can fix it when it occurs but can anyone recommend a Mercurial workflow for pull and merging which <strong>always</strong> avoids this problem? I can work it out by playing with test repos etc., but maybe someone can save me and others some time if they already know.</p>
  
  <p>The simpler the workflow the better, as this is for a small team rather than just one person.</p>
  
  <p>Examples of the issue:</p>
  
  <ul>
  <li><a href="http://mercurial.808500.n3.nabble.com/hgsubstate-not-updated-on-quot-pull-u-quot-or-quot-update-quot-td3995591.html" rel="nofollow">http://mercurial.808500.n3.nabble.com/hgsubstate-not-updated-on-quot-pull-u-quot-or-quot-update-quot-td3995591.html</a></li>
  </ul>
  
  <p><strong>Update - notes on the workings of .hgsubstate</strong></p>
  
  <p>The only two actions that update the <code>.hgsubstate</code> file (when using command line) are as follows:</p>
  
  <ol>
  <li><p><strong>If you pull a version of the outer project, you get whatever .hgsubstate was checked in (obviously)</strong></p></li>
  <li><p><strong>If you commit the <em>outer</em> project, the <code>.hgsubstate</code> is updated to the current parent changeset for the inner project</strong></p></li>
  </ol>
  
  <p>If you update the subrepo but make no changes to the outer project, the outer will show no changes if you do <code>hg status</code>. <strong>However,</strong> if you run <code>hg status -S</code>, you will get file status for the subrepo (as well as the outer project). The file statuses of the subrepo shown are a mixture of:</p>
  
  <p>a) <strong>any uncomitted working copy changes to files in subrepo</strong> </p>
  
  <p>b) <strong>any <em>committed</em> changes to subrepo that are newer than the changeset id in <code>.hgsubstate</code></strong></p>
  
  <p>If you attempt to commit the outer project, even if <code>hg st</code> shows no changes, it will allow you to commit an udpated version of the .hgsubstate file if the subrepo does indeed have a newer tip changeset. So a crucial strategy is to use <code>hg st -S</code> which will show if there's anything pending in your subrepo, such as work copy changes or changesets newer than the id named in <code>.hgsubstate</code>.</p>