75 for f in directories[::-1]: |
76 for f in directories[::-1]: |
76 if match(f) and not os.listdir(repo.wjoin(f)): |
77 if match(f) and not os.listdir(repo.wjoin(f)): |
77 ui.note(_('Removing directory %s\n') % f) |
78 ui.note(_('Removing directory %s\n') % f) |
78 remove(os.rmdir, f) |
79 remove(os.rmdir, f) |
79 |
80 |
80 def _check_missing(ui, repo, missing, force=False): |
81 def _check_fs(ui, repo): |
81 """Abort if there is the chance of having problems with name-mangling fs |
82 """Abort if there is the chance of having problems with name-mangling fs |
82 |
83 |
83 In a name mangling filesystem (e.g. a case insensitive one) |
84 In a name mangling filesystem (e.g. a case insensitive one) |
84 dirstate.walk() can yield filenames different from the ones |
85 dirstate.walk() can yield filenames different from the ones |
85 stored in the dirstate. This already confuses the status and |
86 stored in the dirstate. This already confuses the status and |
86 add commands, but with purge this may cause data loss. |
87 add commands, but with purge this may cause data loss. |
87 |
88 |
88 To prevent this, _check_missing will abort if there are missing |
89 To prevent this, this function will abort if there are uncommitted |
89 files. The force option will let the user skip the check if he |
90 changes. |
90 knows it is safe. |
91 """ |
91 |
92 |
92 Even with the force option this function will check if any of the |
93 # We can't use (files, match) to do a partial walk here - we wouldn't |
93 missing files is still available in the working dir: if so there |
94 # notice a modified README file if the user ran "hg purge readme" |
94 may be some problem with the underlying filesystem, so it |
95 modified, added, removed, deleted = repo.status()[:4] |
95 aborts unconditionally.""" |
96 if modified or added or removed or deleted: |
96 |
97 if not util.checkfolding(repo.path) and not ui.quiet: |
97 found = [f for f in missing if util.lexists(repo.wjoin(f))] |
98 ui.warn(_("Purging on name mangling filesystems is not " |
98 |
99 "fully supported.\n")) |
99 if found: |
100 raise util.Abort(_("outstanding uncommitted changes")) |
100 if not ui.quiet: |
|
101 ui.warn(_("The following tracked files weren't listed by the " |
|
102 "filesystem, but could still be found:\n")) |
|
103 for f in found: |
|
104 ui.warn("%s\n" % f) |
|
105 if util.checkfolding(repo.path): |
|
106 ui.warn(_("This is probably due to a case-insensitive " |
|
107 "filesystem\n")) |
|
108 raise util.Abort(_("purging on name mangling filesystems is not " |
|
109 "yet fully supported")) |
|
110 |
|
111 if missing and not force: |
|
112 raise util.Abort(_("there are missing files in the working dir and " |
|
113 "purge still has problems with them due to name " |
|
114 "mangling filesystems. " |
|
115 "Use --force if you know what you are doing")) |
|
116 |
101 |
117 |
102 |
118 def purge(ui, repo, *dirs, **opts): |
103 def purge(ui, repo, *dirs, **opts): |
119 '''removes files not tracked by mercurial |
104 '''removes files not tracked by mercurial |
120 |
105 |
156 cmdtable = { |
141 cmdtable = { |
157 'purge|clean': |
142 'purge|clean': |
158 (purge, |
143 (purge, |
159 [('a', 'abort-on-err', None, _('abort if an error occurs')), |
144 [('a', 'abort-on-err', None, _('abort if an error occurs')), |
160 ('', 'all', None, _('purge ignored files too')), |
145 ('', 'all', None, _('purge ignored files too')), |
161 ('f', 'force', None, _('purge even when missing files are detected')), |
146 ('f', 'force', None, _('purge even when there are uncommitted changes')), |
162 ('p', 'print', None, _('print the file names instead of deleting them')), |
147 ('p', 'print', None, _('print the file names instead of deleting them')), |
163 ('0', 'print0', None, _('end filenames with NUL, for use with xargs' |
148 ('0', 'print0', None, _('end filenames with NUL, for use with xargs' |
164 ' (implies -p)')), |
149 ' (implies -p)')), |
165 ] + commands.walkopts, |
150 ] + commands.walkopts, |
166 _('hg purge [OPTION]... [DIR]...')) |
151 _('hg purge [OPTION]... [DIR]...')) |