[PATCH] subrepo: Update .hgsubstate in case of deleted subrepo
Saint Germain
saintger at gmail.com
Mon Feb 22 18:45:25 CST 2010
I've discussed with tonfa on IRC and it seems that a flag
'clean-subrepo' or -CS is too specific.
He proposed a flag like '--subrepo' which could be used by other
commands as well (like 'status' ?). But for this kind of decision, we need mpm.
But what do you think about it ?
Anyway, here is the updated patch (on a newer revision than the
previous one)
To: mercurial-devel at selenic.com
Cc:
Affichage de [PATCH] subrepo: Force updating subrepos if using overwrite option ...
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [PATCH] subrepo: Force updating subrepos if using overwrite option
X-Mercurial-Node: 6f6c33d85a8daeb0c3402f7ab951ef390e49f7e6
Message-Id: <6f6c33d85a8daeb0c340.1266885679 at localhost.localdomain>
User-Agent: Mercurial-patchbomb/1.4.3+20-b9e44cc97355
Date: Tue, 23 Feb 2010 01:41:19 +0100
From: Saint Germain <saintger at gmail.com>
To: mercurial-devel at selenic.com
# HG changeset patch
# User Saint Germain <saintger at gmail.com>
# Date 1266885659 -3600
# Branch stable
# Node ID 6f6c33d85a8daeb0c3402f7ab951ef390e49f7e6
# Parent b07d487009b2235f5d03cfa3b0f08be04a4b0a17
subrepo: Force updating subrepos if using overwrite option
Even if .hgsubstate doesn't need updating, subrepos may be 'dirty'. So if using -CS (overwrite)
option, add a check for 'dirty' subrepos and if found, force the update.
diff -r b07d487009b2 -r 6f6c33d85a8d mercurial/commands.py
--- a/mercurial/commands.py Mon Feb 22 01:19:59 2010 +0100
+++ b/mercurial/commands.py Tue Feb 23 01:40:59 2010 +0100
@@ -3241,7 +3241,8 @@
return postincoming(ui, repo, modheads, opts.get('update'), None)
-def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
+def update(ui, repo, node=None, rev=None, clean=False, date=None,
+ check=False, clean_subrepos=False):
"""update working directory
Update the repository's working directory to the specified
@@ -3297,7 +3298,7 @@
rev = cmdutil.finddate(ui, repo, date)
if clean or check:
- return hg.clean(repo, rev)
+ return hg.clean(repo, rev, clean_subrepo=clean_subrepos)
else:
return hg.update(repo, rev)
@@ -3819,6 +3820,8 @@
"^update|up|checkout|co":
(update,
[('C', 'clean', None, _('discard uncommitted changes (no backup)')),
+ ('S', 'clean-subrepos', None,_('use with "clean" (-CS) to discard'
+ ' uncommitted changes (no backup) in subrepositories')),
('c', 'check', None, _('check for uncommitted changes')),
('d', 'date', '', _('tipmost revision matching date')),
('r', 'rev', '', _('revision'))],
diff -r b07d487009b2 -r 6f6c33d85a8d mercurial/hg.py
--- a/mercurial/hg.py Mon Feb 22 01:19:59 2010 +0100
+++ b/mercurial/hg.py Tue Feb 23 01:40:59 2010 +0100
@@ -367,9 +367,9 @@
# naming conflict in clone()
_update = update
-def clean(repo, node, show_stats=True):
+def clean(repo, node, show_stats=True, clean_subrepo=False):
"""forcibly switch the working directory to node, clobbering changes"""
- stats = _merge.update(repo, node, False, True, None)
+ stats = _merge.update(repo, node, False, True, None, clean_subrepo)
if show_stats:
_showstats(repo, stats)
return stats[3] > 0
diff -r b07d487009b2 -r 6f6c33d85a8d mercurial/merge.py
--- a/mercurial/merge.py Mon Feb 22 01:19:59 2010 +0100
+++ b/mercurial/merge.py Tue Feb 23 01:40:59 2010 +0100
@@ -117,7 +117,8 @@
return action
-def manifestmerge(repo, p1, p2, pa, overwrite, partial):
+def manifestmerge(repo, p1, p2, pa, overwrite, partial,
+ overwrite_subrepo=False):
"""
Merge p1 and p2 with ancestor ma and generate merge action list
@@ -186,6 +187,16 @@
if n == m2[f] or m2[f] == a: # same or local newer
if m1.flags(f) != rflags:
act("update permissions", "e", f, rflags)
+ # in case of subrepos, update if overwrite and subrepos is dirty
+ if f == '.hgsubstate':
+ for s in p1.substate:
+ if p1.sub(s).dirty(): # if dirty, force update
+ if overwrite_subrepo:
+ act("remote is newer", "g", f, rflags)
+ elif overwrite:
+ raise util.Abort("subrepos have uncommitted"
+ " changes, use 'hg update -CS' to overwrite\n")
+ break
elif n == a: # remote newer
act("remote is newer", "g", f, rflags)
else: # both changed
@@ -406,7 +417,7 @@
if f:
repo.dirstate.forget(f)
-def update(repo, node, branchmerge, force, partial):
+def update(repo, node, branchmerge, force, partial, clean_subrepos=False):
"""
Perform a merge between the working directory and the given node
@@ -455,6 +466,7 @@
else:
raise util.Abort(_("branch %s not found") % wc.branch())
overwrite = force and not branchmerge
+ overwrite_subrepo = overwrite and clean_subrepos
pl = wc.parents()
p1, p2 = pl[0], repo[node]
pa = p1.ancestor(p2)
@@ -496,7 +508,8 @@
if not util.checkcase(repo.path):
_checkcollision(p2)
action += _forgetremoved(wc, p2, branchmerge)
- action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
+ action += manifestmerge(repo, wc, p2, pa, overwrite, partial,
+ overwrite_subrepo)
### apply phase
if not branchmerge: # just jump to the new rev
diff -r b07d487009b2 -r 6f6c33d85a8d tests/test-subrepo
--- a/tests/test-subrepo Mon Feb 22 01:19:59 2010 +0100
+++ b/tests/test-subrepo Tue Feb 23 01:40:59 2010 +0100
@@ -207,4 +207,20 @@
| "$TESTDIR/filtertmp.py"
rm -rf mercurial mercurial2
+echo % test repositoy clean/overwrite updating
+hg init mercurial
+cd mercurial
+hg init nested
+echo test > nested/foo
+hg -R nested add nested/foo
+echo nested = nested > .hgsub
+hg add .hgsub
+hg ci -mtest
+echo modification > nested/foo
+hg -R nested commit -mmodif
+hg update -C
+hg update -CS
+cd ..
+rm -rf mercurial
+
exit 0
diff -r b07d487009b2 -r 6f6c33d85a8d tests/test-subrepo.out
--- a/tests/test-subrepo.out Mon Feb 22 01:19:59 2010 +0100
+++ b/tests/test-subrepo.out Tue Feb 23 01:40:59 2010 +0100
@@ -266,3 +266,8 @@
default = $HGTMP/test-subrepo/sub/mercurial/main/nested_absolute
[paths]
default = $HGTMP/test-subrepo/sub/mercurial/main/nested_relative
+% test repositoy clean/overwrite updating
+committing subrepository nested
+abort: subrepos have uncommitted changes, use 'hg update -CS' to overwrite
+
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
On Thu, 18 Feb 2010 21:36:31 -0500, Steve Losh <steve at stevelosh.com>
wrote :
> Saint Germain and I have been talking about this patch on IRC. I'm
> happy with this version of the patch, but I think we *might* be able
> to make it even better.
>
> The main question I have is about deleting .hgsubstate automatically
> when the user manually deletes .hgsub entirely.
>
> On the surface this seems like a good idea -- if you delete .hgsub
> that means there are no subrepos any more, so it seems
> like .hgsubstate should also be deleted.
>
> The question I have is: "What happens when person A
> deletes .hgsubstate and .hgsub and then tried to merge with person B
> who has added a new subrepo to .hgsub (and therefore .hgsubstate)?"
>
> Can Mercurial manage to merge the changes cleanly if we
> leave .hgsubstate blank (but not deleted), or are you going to get
> merge conflicts no matter what?
>
> On Feb 18, 2010, at 7:20 PM, Saint Germain wrote:
>
> > # HG changeset patch
> > # User Saint Germain <saintger at gmail.com>
> > # Date 1266538364 -3600
> > # Node ID 52bef2e2c25f10e806a0cdec03ed56e08f5a54c2
> > # Parent b9e44cc97355ff27e05f6cd384061fc12731cec0
> > subrepo: Update .hgsubstate in case of deleted subrepo
> >
> > When a subrepo is deleted from .hgsub, it also need to be removed
> > from .hgsubstate. When .hgsub is removed, .hgsubstate need at least
> > to be blanked out. Previous code was updating .hgsubstate only in
> > case of newly or modified subrepo.
> >
> > diff -r b9e44cc97355 -r 52bef2e2c25f mercurial/localrepo.py
> > --- a/mercurial/localrepo.py Wed Feb 03 16:09:19 2010 +0000
> > +++ b/mercurial/localrepo.py Fri Feb 19 01:12:44 2010 +0100
> > @@ -833,8 +833,9 @@
> > cctx._text = editor(self, cctx, subs)
> > edited = (text != cctx._text)
> >
> > - # commit subs
> > - if subs:
> > + # Update .hgsubstate if commited (added to .hgsub or
> > modified) subs
> > + # or deleted subs (removed from .hgsub)
> > + if subs or '.hgsub' in changes[0]+changes[2]:
> > state = wctx.substate.copy()
> > for s in subs:
> > self.ui.status(_('committing subrepository
> > %s\n') % s) diff -r b9e44cc97355 -r 52bef2e2c25f tests/test-subrepo
> > --- a/tests/test-subrepo Wed Feb 03 16:09:19 2010 +0000
> > +++ b/tests/test-subrepo Fri Feb 19 01:12:44 2010 +0100
> > @@ -160,5 +160,28 @@
> >
> > hg up 5
> > hg merge 4 # try to merge default into br again
> > +cd ..
> > +rm -rf main
> >
> > +echo % test subrepo delete from .hgsubstate
> > +hg init main
> > +mkdir main/nested main/nested2
> > +hg init main/nested
> > +hg init main/nested2
> > +echo test > main/nested/foo
> > +echo test > main/nested2/foo
> > +hg -R main/nested add
> > +hg -R main/nested2 add
> > +hg -R main/nested ci -m test
> > +hg -R main/nested2 ci -m test
> > +echo nested = nested > main/.hgsub
> > +echo nested2 = nested2 >> main/.hgsub
> > +hg -R main add
> > +hg -R main ci -m "nested 1 & 2 added"
> > +echo nested = nested > main/.hgsub
> > +hg -R main ci -m "nested 2 deleted"
> > +cat main/.hgsubstate | sed "s:.* ::"
> > +hg -R main remove main/.hgsub
> > +hg -R main ci -m ".hgsub deleted"
> > +cat main/.hgsubstate
> > exit 0
> > diff -r b9e44cc97355 -r 52bef2e2c25f tests/test-subrepo.out
> > --- a/tests/test-subrepo.out Wed Feb 03 16:09:19 2010 +0000
> > +++ b/tests/test-subrepo.out Fri Feb 19 01:12:44 2010 +0100
> > @@ -243,3 +243,10 @@
> > 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> > 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> > (branch merge, don't forget to commit)
> > +% test subrepo delete from .hgsubstate
> > +adding main/nested/foo
> > +adding main/nested2/foo
> > +adding main/.hgsub
> > +committing subrepository nested2
> > +committing subrepository nested
> > +nested
> > _______________________________________________
> > Mercurial-devel mailing list
> > Mercurial-devel at selenic.com
> > http://selenic.com/mailman/listinfo/mercurial-devel
>
More information about the Mercurial-devel
mailing list