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 |
|
|
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') |
|
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