# HG changeset patch # User Erik Zielke # Date 2011-01-31 12:33:41 # Node ID c19b9282d3a7276e8d48b7db0553fde6130fbccb # Parent 8dc488dfcdb4e23d929d12cfab4037c77d2e227f subrepo: make update -C clean the working directory for svn subrepos This makes 'hg update --clean' behave the same way for both kinds of subrepositories. Before Subversion subrepos did not take the clean parameter into account, but just updated to the given revision and merged uncommitted changes into that. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -249,7 +249,7 @@ def manifestmerge(repo, p1, p2, pa, over def actionkey(a): return a[1] == 'r' and -1 or 0, a -def applyupdates(repo, action, wctx, mctx, actx): +def applyupdates(repo, action, wctx, mctx, actx, overwrite): """apply the merge action list to the working directory wctx is the working copy context @@ -307,7 +307,7 @@ def applyupdates(repo, action, wctx, mct repo.ui.note(_("removing %s\n") % f) audit_path(f) if f == '.hgsubstate': # subrepo states need updating - subrepo.submerge(repo, wctx, mctx, wctx) + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) try: util.unlink(repo.wjoin(f)) except OSError, inst: @@ -317,7 +317,7 @@ def applyupdates(repo, action, wctx, mct removed += 1 elif m == "m": # merge if f == '.hgsubstate': # subrepo states need updating - subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx)) + subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), overwrite) continue f2, fd, flags, move = a[2:] r = ms.resolve(fd, wctx, mctx) @@ -340,7 +340,7 @@ def applyupdates(repo, action, wctx, mct t = None updated += 1 if f == '.hgsubstate': # subrepo states need updating - subrepo.submerge(repo, wctx, mctx, wctx) + subrepo.submerge(repo, wctx, mctx, wctx, overwrite) elif m == "d": # directory rename f2, fd, flags = a[2:] if f: @@ -529,7 +529,7 @@ def update(repo, node, branchmerge, forc if not partial: repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) - stats = applyupdates(repo, action, wc, p2, pa) + stats = applyupdates(repo, action, wc, p2, pa, overwrite) if not partial: repo.dirstate.setparents(fp1, fp2) diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -82,7 +82,7 @@ def writestate(repo, state): ''.join(['%s %s\n' % (state[s][1], s) for s in sorted(state)]), '') -def submerge(repo, wctx, mctx, actx): +def submerge(repo, wctx, mctx, actx, overwrite): """delegated from merge.applyupdates: merging of .hgsubstate file in working context, merging context and ancestor context""" if mctx == actx: # backwards? @@ -114,7 +114,7 @@ def submerge(repo, wctx, mctx, actx): continue elif ld == a: # other side changed debug(s, "other changed, get", r) - wctx.sub(s).get(r) + wctx.sub(s).get(r, overwrite) sm[s] = r elif ld[0] != r[0]: # sources differ if repo.ui.promptchoice( @@ -123,11 +123,11 @@ def submerge(repo, wctx, mctx, actx): % (s, l[0], r[0]), (_('&Local'), _('&Remote')), 0): debug(s, "prompt changed, get", r) - wctx.sub(s).get(r) + wctx.sub(s).get(r, overwrite) sm[s] = r elif ld[1] == a[1]: # local side is unchanged debug(s, "other side changed, get", r) - wctx.sub(s).get(r) + wctx.sub(s).get(r, overwrite) sm[s] = r else: debug(s, "both sides changed, merge with", r) @@ -260,13 +260,13 @@ class abstractsubrepo(object): """ raise NotImplementedError - def get(self, state): + def get(self, state, overwrite=False): """run whatever commands are needed to put the subrepo into this state """ raise NotImplementedError - def merge(self, state): + def merge(self, state, overwrite=False): """merge currently-saved state with the new state.""" raise NotImplementedError @@ -419,7 +419,7 @@ class hgsubrepo(abstractsubrepo): other = hg.repository(self._repo.ui, srcurl) self._repo.pull(other) - def get(self, state): + def get(self, state, overwrite=False): self._get(state) source, revision, kind = state self._repo.ui.debug("getting subrepo %s\n" % self._path) @@ -589,7 +589,9 @@ class svnsubrepo(abstractsubrepo): except OSError: pass - def get(self, state): + def get(self, state, overwrite=False): + if overwrite: + self._svncommand(['revert', '--recursive', self._path]) status = self._svncommand(['checkout', state[0], '--revision', state[1]]) if not re.search('Checked out revision [0-9]+.', status): raise util.Abort(status.splitlines()[-1]) diff --git a/tests/test-subrepo-svn.t b/tests/test-subrepo-svn.t --- a/tests/test-subrepo-svn.t +++ b/tests/test-subrepo-svn.t @@ -264,3 +264,35 @@ update to nullrev (must delete the subre $ hg up null 0 files updated, 0 files merged, 3 files removed, 0 files unresolved $ ls + +Check hg update --clean + $ cd $TESTTMP/sub/t + $ cd s + $ echo c0 > alpha + $ echo c1 > f1 + $ echo c1 > f2 + $ svn add f1 -q + $ svn status + ? a + X externals + ? f2 + M alpha + A f1 + + Performing status on external item at 'externals' + $ cd .. + $ hg update -C + + Fetching external item into '$TESTTMP/sub/t/s/externals' + Checked out external at revision 1. + + Checked out revision 3. + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd s + $ svn status + ? a + X externals + ? f1 + ? f2 + + Performing status on external item at 'externals' diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t --- a/tests/test-subrepo.t +++ b/tests/test-subrepo.t @@ -675,3 +675,31 @@ subrepository: committing subrepository subrepo-1 committing subrepository subrepo-2 $ hg st subrepo-2/file + +Check hg update --clean + $ cd $TESTTMP/sub/t + $ rm -r t/t.orig + $ hg status -S --all + C .hgsub + C .hgsubstate + C a + C s/.hgsub + C s/.hgsubstate + C s/a + C s/ss/a + C t/t + $ echo c1 > s/a + $ cd s + $ echo c1 > b + $ echo c1 > c + $ hg add b + $ cd .. + $ hg status -S + M s/a + A s/b + ? s/c + $ hg update -C + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg status -S + ? s/b + ? s/c