Bugzilla – Bug 438
hg remove without erasing the file (option --keep?)
Last modified: 2012-05-13 05:01:07 EDT
Mathieu Clabaut and Joe Bruce asked on the list to have a way of preserving the file in the working directory when using 'hg remove'. Of course you can backup/restore it or use hg cat or hg revert to retrieve it again, but I think having such a command is important, too.
I did a patch, but I haven't seen an agreement about the option name (--before, --keep ?)
Even if it looks strange or at least self contradictory, I can guess what "hg remove --keep" means where I'm lost with "hg remove --before"...
adding Matt, maybe he has a preference.
maybe something like this? http://hg.einsteinmg.dyndns.org/mercurial_mq/file/tip/adding_keep_option_to_remove.patch
Attached is a patch which add a --keep option : Cleaner semantic for "remove --after" by adding a --keep option. "hg remove" has now 3 options : --after, --keep and --force --after only removes file already deleted --keep always prevent the removed files to be deleted --force forces removing and deletion of file otherwise not removed Note that --keep has precedence over --force Before the patch, --after was used either for keeping or for removing after, and it didn't allow to keep locally modified files.
The patch is good but I have still a couple of problems with it: 1. --after behaviour still looks complicated. I like "--after only removes file already deleted" much better than "Without exact file names, --after will only mark files as removed if they are no longer in the working directory". Try to explain "exact file names" when given files and directories arguments plus --include and --exclude patterns. --after marks deleted files as removed, period. And emit warnings if you pass "exact file names" not referencing deleted files. 2. remove command help is too subtle """ This only removes files from the current branch, not from the entire project history. If the files still exist in the working directory, they will be deleted from it unless invoked with --keep. Modified files are marked as removed, but not actually unlinked unless --force is also given. """ It's not clear the last sentence applies only with --keep. I think we should separate the default behaviour, --keep, --force and --after documentation in self contained sentences/paragraphs to make it simpler. This is obviously easier with [1]. What about: """ This only removes files from the current branch, not from the entire project history. By default, if the files still exist in the working directory, they will be deleted. Modified and added files are not removed. With --force, modified and added files are also deleted and marked as removed. With --keep, all specified files including added and modified ones are marked as removed but not actually unlinked. With --after, only files missing from the working directory are marked as removed. --keep and --after override --force. """ (I am not sure the line about --force being overriden is really necessary). 3. --after --force forgets added files. This an easily solved bug. What do you think ?
I don't like this change. There should be exactly one option that simply marks a file as deleted and doesn't care whether the file is really present or not. Perhaps --after isn't a good name for that option, but then that should be the focus of the patch.
Fine with me, let us keep things simple. To sum up : 1. hg remove Remove files from the repo, whether they exists or not in the working dir. It also unlink the file if it exists. Option --force is used for added an modified files. 2. hg remove --keep The same as hg remove, but never unlink the file. Some alternative names for --keep : --repo-only --only --no-delete --preserve The last question is : will someone miss the following addremove like behavior "Without exact file names, --after will only mark files as removed if they are no longer in the working directory."
> 2. hg remove --keep > The same as hg remove, but never unlink the file. Did you mean "The same as hg remove --force, ..." ? The name is good for, at least one similar option exists in MQ. > The last question is : will someone miss the following addremove > like behavior "Without exact file names, --after will only mark > files as removed if they are no longer in the working directory." Not me.
Attached is a patch proposal (rm-keep.patch, which also include in a separate changeset small additions to test-remove): Except for modified or added files, 'hg remove' now always remove files from the repository and delete them. - '--force' option is needed for added and modified files, - '--keep' option always preserves the files in the working directory. Before that patch, '--after' was used either for keeping local files or for removing files after manual deletion, but: - '--after' didn't allow to keep locally modified files, - '--force' didn't delete added files as advertised. (Perhaps should we change the subject as it is now more a bug about remove --after of modified files... Don't know what is the local policy about changing ticket description)
So what's blocking this? Is the proposed behavior good enough? I'd like to get this in.
We still need a consensus if we just want to fix --after and --force, or if we want to introduce --keep and fix --force. Pro for --after: No extra option. Pro for --keep: No implied additional meaning for --after, easy to rm --keep whole directories. I think the whole-directory part justifies introducing --keep. But should 'hg rm --after foo' on an existing foo complain that foo still exists or should it be equivalent to 'hg rm --keep foo'?
I think having --keep would be good. hg rm --after foo should still complain IMO, but I think that the behavior for hg rm --after --force foo should be changed to not-delete and not-complain.
I do not like very much even the current 'after' semantic. Hg rm --help shows : -A --after record remove without deleting It looks very difficult to me to grasp the logical link between "after" and "record remove without deleting"... Hence my previous proposal. Only keep two options : '--keep' which always preserves the files in the working directory. '--force' which is needed to delete added and modified files pro: still only two options, semantic is more straight, easy to rm --keep whole directories. cons: get rid of '--after' used in some other places.
As I wrote in msg5457, we need keep and after: hg rm --after foo: Look for manually deleted (missing) files in foo and mark them as removed. hg rm --keep foo: Mark all files below the directory foo as removed, but don't delete them
"rm foo/bar && hg rm --keep foo/bar" is just as stupid as "hg rm -A foo/bar" on an existing file --keep should say "oh, there is no file" and abort, --after should say "oh, there is a file" and abort. (with exact file names, different rules for specifying directories of course)
I've just pushed 8e3b651382f5 to crew, which fixes this by changing the interaction of --after and --force. It includes some improved documentation.
In main, resolving.
Thanks a lot ! (I still feel that --after --force is not very intuitive for "remove from repo but keep in working directory", but it is a very minor problem regarding the bug which is corrected)
Maybe it is good to not have --keep, because of the implications (doesn't propagate to repos pulling from here)
--- Bug imported by bugzilla@serpentine.com 2012-05-12 08:38 EDT --- This bug was previously known as _bug_ 438 at http://mercurial.selenic.com/bts/issue438 Imported an attachment (id=706) Imported an attachment (id=707)