##// END OF EJS Templates
remove: recurse into subrepositories with --subrepos/-S flag...
Matt Harbison -
r23325:4165cfd6 default
parent child Browse files
Show More
@@ -2052,21 +2052,44 b' def forget(ui, repo, match, prefix, expl'
2052 forgot.extend(forget)
2052 forgot.extend(forget)
2053 return bad, forgot
2053 return bad, forgot
2054
2054
2055 def remove(ui, repo, m, after, force):
2055 def remove(ui, repo, m, prefix, after, force, subrepos):
2056 join = lambda f: os.path.join(prefix, f)
2056 ret = 0
2057 ret = 0
2057 s = repo.status(match=m, clean=True)
2058 s = repo.status(match=m, clean=True)
2058 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2059 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2059
2060
2061 wctx = repo[None]
2062
2063 if subrepos:
2064 for subpath in sorted(wctx.substate):
2065 sub = wctx.sub(subpath)
2066 try:
2067 submatch = matchmod.narrowmatcher(subpath, m)
2068 if sub.removefiles(ui, submatch, prefix, after, force,
2069 subrepos):
2070 ret = 1
2071 except error.LookupError:
2072 ui.status(_("skipping missing subrepository: %s\n")
2073 % join(subpath))
2074
2060 # warn about failure to delete explicit files/dirs
2075 # warn about failure to delete explicit files/dirs
2061 wctx = repo[None]
2062 for f in m.files():
2076 for f in m.files():
2063 if f in repo.dirstate or f in wctx.dirs():
2077 def insubrepo():
2078 for subpath in wctx.substate:
2079 if f.startswith(subpath):
2080 return True
2081 return False
2082
2083 if f in repo.dirstate or f in wctx.dirs() or (subrepos and insubrepo()):
2064 continue
2084 continue
2065 if os.path.exists(m.rel(f)):
2085
2066 if os.path.isdir(m.rel(f)):
2086 if os.path.exists(m.rel(join(f))):
2067 ui.warn(_('not removing %s: no tracked files\n') % m.rel(f))
2087 if os.path.isdir(m.rel(join(f))):
2088 ui.warn(_('not removing %s: no tracked files\n')
2089 % m.rel(join(f)))
2068 else:
2090 else:
2069 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2091 ui.warn(_('not removing %s: file is untracked\n')
2092 % m.rel(join(f)))
2070 # missing files will generate a warning elsewhere
2093 # missing files will generate a warning elsewhere
2071 ret = 1
2094 ret = 1
2072
2095
@@ -2075,22 +2098,22 b' def remove(ui, repo, m, after, force):'
2075 elif after:
2098 elif after:
2076 list = deleted
2099 list = deleted
2077 for f in modified + added + clean:
2100 for f in modified + added + clean:
2078 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
2101 ui.warn(_('not removing %s: file still exists\n') % m.rel(join(f)))
2079 ret = 1
2102 ret = 1
2080 else:
2103 else:
2081 list = deleted + clean
2104 list = deleted + clean
2082 for f in modified:
2105 for f in modified:
2083 ui.warn(_('not removing %s: file is modified (use -f'
2106 ui.warn(_('not removing %s: file is modified (use -f'
2084 ' to force removal)\n') % m.rel(f))
2107 ' to force removal)\n') % m.rel(join(f)))
2085 ret = 1
2108 ret = 1
2086 for f in added:
2109 for f in added:
2087 ui.warn(_('not removing %s: file has been marked for add'
2110 ui.warn(_('not removing %s: file has been marked for add'
2088 ' (use forget to undo)\n') % m.rel(f))
2111 ' (use forget to undo)\n') % m.rel(join(f)))
2089 ret = 1
2112 ret = 1
2090
2113
2091 for f in sorted(list):
2114 for f in sorted(list):
2092 if ui.verbose or not m.exact(f):
2115 if ui.verbose or not m.exact(f):
2093 ui.status(_('removing %s\n') % m.rel(f))
2116 ui.status(_('removing %s\n') % m.rel(join(f)))
2094
2117
2095 wlock = repo.wlock()
2118 wlock = repo.wlock()
2096 try:
2119 try:
@@ -5086,7 +5086,7 b' def recover(ui, repo):'
5086 [('A', 'after', None, _('record delete for missing files')),
5086 [('A', 'after', None, _('record delete for missing files')),
5087 ('f', 'force', None,
5087 ('f', 'force', None,
5088 _('remove (and delete) file even if added or modified')),
5088 _('remove (and delete) file even if added or modified')),
5089 ] + walkopts,
5089 ] + subrepoopts + walkopts,
5090 _('[OPTION]... FILE...'),
5090 _('[OPTION]... FILE...'),
5091 inferrepo=True)
5091 inferrepo=True)
5092 def remove(ui, repo, *pats, **opts):
5092 def remove(ui, repo, *pats, **opts):
@@ -5131,7 +5131,8 b' def remove(ui, repo, *pats, **opts):'
5131 raise util.Abort(_('no files specified'))
5131 raise util.Abort(_('no files specified'))
5132
5132
5133 m = scmutil.match(repo[None], pats, opts)
5133 m = scmutil.match(repo[None], pats, opts)
5134 return cmdutil.remove(ui, repo, m, after, force)
5134 subrepos = opts.get('subrepos')
5135 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5135
5136
5136 @command('rename|move|mv',
5137 @command('rename|move|mv',
5137 [('A', 'after', None, _('record a rename that has already occurred')),
5138 [('A', 'after', None, _('record a rename that has already occurred')),
@@ -129,6 +129,10 b' Interaction with Mercurial Commands'
129 elements. Subversion subrepositories are currently silently
129 elements. Subversion subrepositories are currently silently
130 ignored.
130 ignored.
131
131
132 :remove: remove does not recurse into subrepositories unless
133 -S/--subrepos is specified. Git and Subversion subrepositories
134 are currently silently ignored.
135
132 :update: update restores the subrepos in the state they were
136 :update: update restores the subrepos in the state they were
133 originally committed in target changeset. If the recorded
137 originally committed in target changeset. If the recorded
134 changeset is not available in the current subrepository, Mercurial
138 changeset is not available in the current subrepository, Mercurial
@@ -501,6 +501,13 b' class abstractsubrepo(object):'
501 def forget(self, ui, match, prefix):
501 def forget(self, ui, match, prefix):
502 return ([], [])
502 return ([], [])
503
503
504 def removefiles(self, ui, matcher, prefix, after, force, subrepos):
505 """remove the matched files from the subrepository and the filesystem,
506 possibly by force and/or after the file has been removed from the
507 filesystem. Return 0 on success, 1 on any warning.
508 """
509 return 1
510
504 def revert(self, ui, substate, *pats, **opts):
511 def revert(self, ui, substate, *pats, **opts):
505 ui.warn('%s: reverting %s subrepos is unsupported\n' \
512 ui.warn('%s: reverting %s subrepos is unsupported\n' \
506 % (substate[0], substate[2]))
513 % (substate[0], substate[2]))
@@ -854,6 +861,12 b' class hgsubrepo(abstractsubrepo):'
854 os.path.join(prefix, self._path), True)
861 os.path.join(prefix, self._path), True)
855
862
856 @annotatesubrepoerror
863 @annotatesubrepoerror
864 def removefiles(self, ui, matcher, prefix, after, force, subrepos):
865 return cmdutil.remove(ui, self._repo, matcher,
866 os.path.join(prefix, self._path), after, force,
867 subrepos)
868
869 @annotatesubrepoerror
857 def revert(self, ui, substate, *pats, **opts):
870 def revert(self, ui, substate, *pats, **opts):
858 # reverting a subrepo is a 2 step process:
871 # reverting a subrepo is a 2 step process:
859 # 1. if the no_backup is not set, revert all modified
872 # 1. if the no_backup is not set, revert all modified
@@ -210,7 +210,7 b' Show all commands + options'
210 merge: force, rev, preview, tool
210 merge: force, rev, preview, tool
211 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
211 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
212 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
212 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
213 remove: after, force, include, exclude
213 remove: after, force, subrepos, include, exclude
214 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
214 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
215 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
215 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
216 summary: remote
216 summary: remote
@@ -1944,6 +1944,9 b' Dish up an empty repo; serve it cold.'
1944 <tr><td>-f</td>
1944 <tr><td>-f</td>
1945 <td>--force</td>
1945 <td>--force</td>
1946 <td>remove (and delete) file even if added or modified</td></tr>
1946 <td>remove (and delete) file even if added or modified</td></tr>
1947 <tr><td>-S</td>
1948 <td>--subrepos</td>
1949 <td>recurse into subrepositories</td></tr>
1947 <tr><td>-I</td>
1950 <tr><td>-I</td>
1948 <td>--include PATTERN [+]</td>
1951 <td>--include PATTERN [+]</td>
1949 <td>include names matching the given patterns</td></tr>
1952 <td>include names matching the given patterns</td></tr>
@@ -110,6 +110,17 b' Check that deep archiving works'
110 $ hg ci -Sm "add test.txt"
110 $ hg ci -Sm "add test.txt"
111 committing subrepository sub1
111 committing subrepository sub1
112 committing subrepository sub1/sub2 (glob)
112 committing subrepository sub1/sub2 (glob)
113
114 .. but first take a detour through some deep removal testing
115
116 $ hg remove -S -I 're:.*.txt' sub1
117 removing sub1/sub2/folder/test.txt (glob)
118 removing sub1/sub2/test.txt (glob)
119 $ hg status -S
120 R sub1/sub2/folder/test.txt
121 R sub1/sub2/test.txt
122 $ hg update -Cq
123
113 $ hg --config extensions.largefiles=! archive -S ../archive_all
124 $ hg --config extensions.largefiles=! archive -S ../archive_all
114 $ find ../archive_all | sort
125 $ find ../archive_all | sort
115 ../archive_all
126 ../archive_all
General Comments 0
You need to be logged in to leave comments. Login now