[PATCH 4 of 4] revert: add support for reverting added subrepos
Angel Ezquerra
angel.ezquerra at gmail.com
Wed Mar 28 16:31:33 CDT 2012
# HG changeset patch
# User Angel Ezquerra <angel.ezquerra at gmail.com>
# Date 1332927737 -7200
# Node ID 012faafa7816588896ce7e885b66e72b80975b1a
# Parent 4ac4d56de5ab18913f7cf8d78bb6458149be27a1
revert: add support for reverting added subrepos
Detect subrepos that are found on the working directory but not on the parent
revision. This means that they have been added to the .hgsub file (and possibly
to the .hgsubstate file).
To "remove them", parse the .hgsub and .hgsubstate files and remove any lines
that refert to the added subrepo.
NOTES / ISSUES:
* The "cmdutil.removesub" function could be folded into the remove command.
* Is modifying the .hgsub and .hgsubstate files automatically OK?
* This may change the line endings on the .hgsub and .hgsubstate files
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1349,12 +1349,15 @@
m.bad = lambda x, y: False
for abs in repo.walk(m):
names[abs] = m.rel(abs), m.exact(abs)
+ wdsubs = [s for s in repo[None].substate if m(s)]
# walk target manifest.
def badfn(path, msg):
if path in names:
return
+ if path in wdsubs:
+ return
if path in repo[node].substate:
return
path_ = path + '/'
@@ -1500,13 +1503,80 @@
checkout(f)
normal(f)
- if targetsubs:
+ if targetsubs or wdsubs:
# Revert the subrepos on the revert list
for sname in targetsubs:
ctx.sub(sname).revert(
- ui, ctx.substate[sname], *pats, **opts)
+ ui, ctx.substate[sname], *pats, **opts)
+ # Revert the subrepos that have been added to the working directory
+ for sname in wdsubs:
+ if sname not in targetsubs:
+ removesub(ui, repo, sname)
finally:
wlock.release()
+
+def removesub(ui, repo, spath):
+ # remove the corresponding lines from the .hgsub and .hgsubstate files
+ ui.status(_('removing subrepo %s\n') % spath)
+
+ spath = os.path.normcase(spath)
+ hgsubpath = repo.wjoin('.hgsub')
+ hgsubstatepath = repo.wjoin('.hgsubstate')
+
+ try:
+ h = open(hgsubpath, 'r')
+ hgsub = h.readlines()
+ h.close()
+ except:
+ ui.warn(_('could not open .hgsub file for reading'))
+ return
+
+ try:
+ h = open(hgsubstatepath, 'r')
+ hgsubstate = h.readlines()
+ h.close()
+ except:
+ ui.warn(_('could not open .hgsubstate file for reading'))
+ return
+
+ # filter any lines that refer to the selected subrepo
+ def filterlines(lines, filterfunc):
+ filteredlines = []
+ for line in lines:
+ if filterfunc(line):
+ continue
+ filteredlines.append(line)
+ return filteredlines
+
+ def hgsubmatch(line):
+ subpath = os.path.normcase(line.split('=')[0].strip())
+ return subpath == spath
+
+ def hgsubstatematch(line):
+ subpath = line.split()[1].strip()
+ return subpath == spath
+
+ newhgsub = filterlines(hgsub, hgsubmatch)
+ if len(newhgsub) == len(hgsub):
+ ui.warn(_('repository %s is not present on .hgsub file') % spath)
+ return
+
+ # it does not matter if the subrepo is not found on the .hgsubsate file
+ newhgsubstate = filterlines(hgsubstate, hgsubstatematch)
+
+ # Update the .hgsub and .hgsubstate files
+ outdata = [(hgsubpath, newhgsub)]
+ if len(newhgsubstate) != len(hgsubstate):
+ outdata.append((hgsubstatepath, newhgsubstate))
+
+ for fname, lines in outdata:
+ try:
+ h = open(fname, 'w')
+ h.writelines(lines)
+ h.close()
+ except:
+ ui.warn(_('could not open %s file for writing') % fname)
+ return
def command(table):
'''returns a function object bound to table which can be used as
More information about the Mercurial-devel
mailing list