comparison mercurial/commands.py @ 6346:8e3b651382f5

improved semantics for remove (issue438) - Added files are never deleted (only removed with --force). - Modified files can only be removed with --force. - With --after, only deleted files are removed. - With --after --force, all files are removed but not deleted.
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Sat, 22 Mar 2008 10:07:49 +0100
parents 4b0c9c674707
children 3b42f7ac6916
comparison
equal deleted inserted replaced
6345:351da911f739 6346:8e3b651382f5
2125 def remove(ui, repo, *pats, **opts): 2125 def remove(ui, repo, *pats, **opts):
2126 """remove the specified files on the next commit 2126 """remove the specified files on the next commit
2127 2127
2128 Schedule the indicated files for removal from the repository. 2128 Schedule the indicated files for removal from the repository.
2129 2129
2130 This only removes files from the current branch, not from the 2130 This only removes files from the current branch, not from the entire
2131 entire project history. If the files still exist in the working 2131 project history. -A can be used to remove only files that have already
2132 directory, they will be deleted from it. If invoked with --after, 2132 been deleted, -f can be used to force deletion, and -Af can be used
2133 files are marked as removed, but not actually unlinked unless --force 2133 to remove files from the next revision without deleting them.
2134 is also given. Without exact file names, --after will only mark 2134
2135 files as removed if they are no longer in the working directory. 2135 The following table details the behavior of remove for different file
2136 states (columns) and option combinations (rows). The file states are
2137 Added, Clean, Modified and Missing (as reported by hg status). The
2138 actions are Warn, Remove (from branch) and Delete (from disk).
2139
2140 A C M !
2141 none W RD W R
2142 -f R RD RD R
2143 -A W W W R
2144 -Af R R R R
2136 2145
2137 This command schedules the files to be removed at the next commit. 2146 This command schedules the files to be removed at the next commit.
2138 To undo a remove before that, see hg revert. 2147 To undo a remove before that, see hg revert.
2139 2148 """
2140 Modified files and added files are not removed by default. To 2149
2141 remove them, use the -f/--force option. 2150 after, force = opts.get('after'), opts.get('force')
2142 """ 2151 if not pats and not after:
2143 if not opts['after'] and not pats:
2144 raise util.Abort(_('no files specified')) 2152 raise util.Abort(_('no files specified'))
2153
2145 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) 2154 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
2146 exact = dict.fromkeys(files)
2147 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5] 2155 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
2148 modified, added, removed, deleted, unknown = mardu 2156 modified, added, removed, deleted, unknown = mardu
2157
2149 remove, forget = [], [] 2158 remove, forget = [], []
2150 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): 2159 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
2160
2151 reason = None 2161 reason = None
2152 if abs in modified and not opts['force']: 2162 if abs in removed or abs in unknown:
2153 reason = _('is modified (use -f to force removal)') 2163 continue
2164
2165 # last column
2166 elif abs in deleted:
2167 remove.append(abs)
2168
2169 # rest of the third row
2170 elif after and not force:
2171 reason = _('still exists (use -f to force removal)')
2172
2173 # rest of the first column
2154 elif abs in added: 2174 elif abs in added:
2155 if opts['force']: 2175 if not force:
2176 reason = _('has been marked for add (use -f to force removal)')
2177 else:
2156 forget.append(abs) 2178 forget.append(abs)
2157 continue 2179
2158 reason = _('has been marked for add (use -f to force removal)') 2180 # rest of the third column
2159 exact = 1 # force the message 2181 elif abs in modified:
2160 elif abs not in repo.dirstate: 2182 if not force:
2161 reason = _('is not managed') 2183 reason = _('is modified (use -f to force removal)')
2162 elif opts['after'] and not exact and abs not in deleted: 2184 else:
2163 continue 2185 remove.append(abs)
2164 elif abs in removed: 2186
2165 continue 2187 # rest of the second column
2188 elif not reason:
2189 remove.append(abs)
2190
2166 if reason: 2191 if reason:
2167 if exact: 2192 ui.warn(_('not removing %s: file %s\n') % (rel, reason))
2168 ui.warn(_('not removing %s: file %s\n') % (rel, reason)) 2193 elif ui.verbose or not exact:
2169 else: 2194 ui.status(_('removing %s\n') % rel)
2170 if ui.verbose or not exact: 2195
2171 ui.status(_('removing %s\n') % rel)
2172 remove.append(abs)
2173 repo.forget(forget) 2196 repo.forget(forget)
2174 repo.remove(remove, unlink=opts['force'] or not opts['after']) 2197 repo.remove(remove, unlink=not after)
2175 2198
2176 def rename(ui, repo, *pats, **opts): 2199 def rename(ui, repo, *pats, **opts):
2177 """rename files; equivalent of copy + remove 2200 """rename files; equivalent of copy + remove
2178 2201
2179 Mark dest as copies of sources; mark sources for deletion. If 2202 Mark dest as copies of sources; mark sources for deletion. If
3123 ] + remoteopts, 3146 ] + remoteopts,
3124 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')), 3147 _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
3125 "recover": (recover, [], _('hg recover')), 3148 "recover": (recover, [], _('hg recover')),
3126 "^remove|rm": 3149 "^remove|rm":
3127 (remove, 3150 (remove,
3128 [('A', 'after', None, _('record remove without deleting')), 3151 [('A', 'after', None, _('record delete for missing files')),
3129 ('f', 'force', None, _('remove file even if modified')), 3152 ('f', 'force', None,
3153 _('remove (and delete) file even if added or modified')),
3130 ] + walkopts, 3154 ] + walkopts,
3131 _('hg remove [OPTION]... FILE...')), 3155 _('hg remove [OPTION]... FILE...')),
3132 "rename|mv": 3156 "rename|mv":
3133 (rename, 3157 (rename,
3134 [('A', 'after', None, _('record a rename that has already occurred')), 3158 [('A', 'after', None, _('record a rename that has already occurred')),