RFC: Change the default for "mv-rm-files" to "on"
(1.1) By Daniel Dumitriu (danield) on 2025-04-01 08:10:56 edited from 1.0 [link] [source]
Background: Fossil's mv
command does not rename files on disk, unless the option --hard
is given or the setting mv-rm-files
is on
. That setting still defaults for fear of breaking existing scripts to off
.
The subject comes up regularly in forum, last time yesterday.
The current behavior is different from most (all?) of the modern SCMs (git, hg, svn, pijul, darcs) and this tends to confuse new (and older) users, and is prone to create larger problems when the subsequent OS's "move" is forgotten.
For these reasons, I advocate that we change the default to on
; users preferring the current behavior can set the setting to on
, or use the --soft
option.
EDIT: In the last sentence: users can set the setting to off
, of course.
(2) By Stephan Beal (stephan) on 2025-04-01 09:03:25 in reply to 1.1 [link] [source]
For these reasons, I advocate that we change the default to on;
FWIW: +1
(3) By Warren Young (wyoung) on 2025-04-01 09:39:27 in reply to 1.1 [link] [source]
I always set that flag here, but my understanding was that the reason for the default was that drh wanted to follow CVS’s conventions. Only if that is no longer a design goal can we flip this default.
(4.1) By Richard Hipp (drh) on 2025-04-01 10:48:56 edited from 4.0 in reply to 3 [link] [source]
drh wanted to follow CVS’s conventions
A more accurate characterization: Prior exposure to CVS had so conditioned my mind, that the --hard behavior never occurred to me when I was first designing Fossil. Then latter when --hard was proposed, it was made opt-in to avoid backwards-compatibility issues.
(5) By jvdh (veedeehjay) on 2025-04-01 10:47:16 in reply to 4.1 [link] [source]
understood. but even CVS's successor (subversion) already did not keep/adopt this legacy behaviour presumably because it was found to be "suboptimal"?
in any case, what would be a fair assessment of the current situation, so many years down the road?
how much pain/friction would it cause today for how many long-time users to switch off mv --hard
in their settings (in case they really prefer and rely on the current default) if the default were changed vs. how much pain/friction (and confusion!) does the current default behaviour cause for (hopefully continuously arriving) new users coming from other VCSes and expecting (and very possibly also preferring) "standard" mv
behaviour? I really believe it would be a good (small) thing to change the default in the future.
(6) By bohwaz on 2025-04-01 11:09:34 in reply to 1.1 [link] [source]
I'm all for it yes, but maybe only for new repos / new clones, so that your existing behaviour doesn't change unexpectedly.
(7) By Martin Gagnon (mgagnon) on 2025-04-01 11:51:47 in reply to 6 [link] [source]
Even if I never bother to turn on this mv-rm-files
and got used to the legacy way, I'm in for it also.
(I never used git or any other modern scm, I came directly from CVS)
but maybe only for new repos / new clones
I think this would be a lot more confusing.
If it's default globally, someone could get a kind of moment of surprise once, if it behaves differently on different repo, those surprising moment could happens many times on a long time span, especially that it would not be obvious that behaviour happens only on new repo or clones.
Also, moving files in repo is relatively rare, creating/cloning repo can be rare compared with using existing repo depending on user, so it could take a while before one realized that the behaviour is different on some repository.
I even don't see a case where someone would want the mv-rm-files
setting set differently on different repositories in the first place. Probably it's possible now just because we don't have global only settings ?
(8) By Stephan Beal (stephan) on 2025-04-01 12:32:54 in reply to 5 [link] [source]
understood. but even CVS's successor (subversion) already did not keep/adopt this legacy behaviour presumably because it was found to be "suboptimal"?
Trivia: fossil was directly inspired by CVSTrac, so initially inherited more from CVS than SVN. (Funnily enough, CVSTrac's source code is now hosted in fossil.)
(9) By sean (jungleboogie) on 2025-04-01 18:00:36 in reply to 1.1 [link] [source]
I have moved files on the OS and then via fossil. Having it being a single operation would be neat, but I don't find the need to move files that frequent.
However, it being similar to the other players makes sense.
What's the output like if you have this enabled? It might be nice to have it report the file was moved on the OS and renamed in fossil, if that's not already present.
(10.1) By Richard Hipp (drh) on 2025-04-01 19:11:46 edited from 10.0 in reply to 1.1 [link] [source]
The "fossil undo" command does not (currently) undo a "fossil rm --hard". Perhaps that should be fixed before "--hard" becomes the default?
(11) By Mike Swanson (chungy) on 2025-04-01 19:19:55 in reply to 10.1 [link] [source]
That would make Fossil internally consistent with itself. Every command that modifies the state of a check-out should create undo data by default (which is overridable in some commands with --disable-undo
).
(12) By Andy Bradford (andybradford) on 2025-04-01 20:20:14 in reply to 1.1 [link] [source]
> Background: Fossil's mv command does not rename files on disk, unless > the option --hard is given or the setting mv-rm-files is on. Why not just direct new users to "fossil rename" and "fossil forget" and leave the historical behavior as-is? https://marc.info/?l=fossil-users&m=144565852143593&w=2 Maybe nobody is really using "fossil rename" or "fossil forget"? Andy
(13.1) By Andy Bradford (andybradford) on 2025-04-01 20:29:00 edited from 13.0 in reply to 9 [link] [source]
> What's the output like if you have this enabled? I assume it would be similar to just using the mv --hard option: $ fossil mv --hard OLDFILE NEWFILE RENAME OLDFILE NEWFILE MOVED_FILE /tmp/new/OLDFILE $ fossil status repository: /tmp/new.fossil local-root: /tmp/new/ config-db: /home/amb/.fossil checkout: 88f92706e55d6d032d188a4220c1a4fee00f8ef7 2025-04-01 20:25:59 UTC parent: 9aa5e05ba117c1e674502930d05c262d8b820799 2025-04-01 20:25:44 UTC tags: trunk comment: OLDFILE (user: amb) RENAMED OLDFILE -> NEWFILE versus: $ fossil mv OLDFILE NEWFILE RENAME OLDFILE NEWFILE $ fossil status repository: /tmp/new.fossil local-root: /tmp/new/ config-db: /home/amb/.fossil checkout: 88f92706e55d6d032d188a4220c1a4fee00f8ef7 2025-04-01 20:25:59 UTC parent: 9aa5e05ba117c1e674502930d05c262d8b820799 2025-04-01 20:25:44 UTC tags: trunk comment: OLDFILE (user: amb) MISSING OLDFILE -> NEWFILE And furthermore, if you try to commit, you'll be told that you're missing a file: $ fossil commit missing file: /tmp/new/NEWFILE aborting due to prior errors
(14.1) By Andy Bradford (andybradford) on 2025-04-01 20:38:27 edited from 14.0 in reply to 10.1 [link] [source]
> The "fossil undo" command does not (currently) undo a "fossil rm --hard". [I just realize that what I demonstrated was the ability to "undo" a revert, not the actual "fossil rm" command.] It does seem to work fine with the current default behavior without --hard: $ cat OLDFILE 5403 $ echo $RANDOM >> OLDFILE $ cat OLDFILE 5403 11599 $ fossil mv OLDFILE NEWFILE RENAME OLDFILE NEWFILE $ cp OLDFILE NEWFILE $ fossil diff Index: NEWFILE ================================================================== --- NEWFILE +++ NEWFILE @@ -1,1 +1,2 @@ 5403 +11599 Ok, watch me pull a rabbit out of my hat: $ fossil status repository: /tmp/new.fossil local-root: /tmp/new/ config-db: /home/amb/.fossil checkout: 88f92706e55d6d032d188a4220c1a4fee00f8ef7 2025-04-01 20:25:59 UTC parent: 9aa5e05ba117c1e674502930d05c262d8b820799 2025-04-01 20:25:44 UTC tags: trunk comment: OLDFILE (user: amb) EDITED OLDFILE -> NEWFILE $ fossil revert DELETE NEWFILE REVERT OLDFILE "fossil undo" is available to undo changes to the working checkout. $ ls OLDFILE $ cat OLDFILE 5403 $ fossil undo NEW NEWFILE UNDO OLDFILE $ cat OLDFILE 5403 11599 $ cat NEWFILE 5403 11599 Presto!
(15) By Mike Swanson (chungy) on 2025-04-01 21:02:28 in reply to 12 [link] [source]
Not showing up in the standard fossil help
output probably contributes to mv
and rm
being the first reach. Even still, your proposal would require changing the current behavior of commands:
The 'rename' command never renames or moves files on disk, even when the command line options and/or the 'mv-rm-files' setting would otherwise require it to do so.
The 'forget' command never removes files from disk, even when the command line options and/or the 'mv-rm-files' setting would otherwise require it to do so.
These are effectively synonyms for fossil mv --soft
and fossil rm --soft
.
(16) By Andy Bradford (andybradford) on 2025-04-01 21:14:56 in reply to 15 [link] [source]
> Even still, your proposal would require changing the current behavior > of commands: No, I was not proposing that the behavior of "fossil rename" and "fossil forget" be changed. In fact, that would completely go against their intended purpose as detailed in the linked discussion that I provided. I'm not sure what I was thinking when I suggested those two commands, honestly, but since this is a Fossil Forum, I didn't bother deleting my now fossilized comment. Apologies for muddying the waters.
(18) By Trevor (MelvaigT) on 2025-04-02 00:10:10 in reply to 15 [link] [source]
Not synonyms, or at least put it the other way around: mv --soft
is a synonym for rename
. But why would you want to do that?
I believe a better way to think of this is that rename
and forget
are fundamental VCS operations to say that when the current checkout is committed rename x y
means the file previously known as x
is now to be known as y
and forget f
means that the history of file f
comes to an end. mv
combines rename
with one of its possible implementations viz the unix style mv, and rm|delete
(those really are synonyms) combines forget
with one of its possible implementations viz the unix style rm.
Compare this with fossil add
: You are supplying information to the VCS that a file f
will appear and we want its future lifetime to be tracked. In this case there is no obvious possible implementation so there is no associated command.
rename
and forget
should be the prime entry points with regard to the help text, the other commands are just for convenience where a simple implementation is suitable, and appear as 'see also' in the command they relate to.
Notice that described in this way you don't need --hard
and --soft
and their associated setting at all, other than for compatibilty reasons. Perhaps even try to address the issue initially with just changing the documentation?
If we gave a bit more description of what effect these commands have when viewed in a timeline perhaps newcomers from Git and friends would realise sooner that the similarly named commands from their own VCS might not be as close to the Fossil offering as the names suggest.
(19) By Andy Bradford (andybradford) on 2025-04-02 01:43:25 in reply to 1.1 [link] [source]
> The current behavior is different from most (all?) of the modern SCMs I don't find this a very convincing argument since I don't see "different from other SCMs" as necessarily a bad thing. This could just be one of those "The Fossil Way" features. Though, it would be interesting to hear some good justification for it. At the same time, I also don't have a strong argument for the current behavior as I rarely use "fossil mv" or "fossil rm". I can see perfectly legitimate reasons for both behaviors. Also, I don't really have a strong preference one way or the other except that changing the behavior might break existing use made by others. Otherwise, if the consensus is to change it, then I suppose go for it. Andy
(20) By DB (ACB) on 2025-04-02 06:22:22 in reply to 19 [link] [source]
I've used fossil mv
quite a bit and learned the hard way early on: 1) always use fossil to rename &/or move files around 2) always include --hard
to actually make the change in the OS file system/checkout. Both behaviors were counter intuitive to me.
Perhaps fossil's change log should have a section like some other projects where some changes in behavior are at the top, like OpenSSH's "Potentially-incompatible changes" section. Thus folks who delve into these matters can read about them first before installing the latest version. Admittedly it seems people around here are (re)building fossil hourly/daily/weekly so they might catch it sooner, but my guess is not all fossil users are on the bleeding edge. So the people they look to will be able to adjust their workflows if need be, before their end users upgrade.
My repo of recipes had grown to be a long list and it was time to categorize them in folders. I don't have a fancy renaming script yet so it was all done at the command line. Thankfully 'f' is aliased to fossil, saving a few keystrokes, and thanks to Stephan, I added the global setting (now redundant with this change) to make fossil mv
always --hard
, saving a few more.
Fossil is awesome to fossilize one's data, but not all of its behaviors should necessarily be ossified. :-)
(21) By Jörgen Kosche (jkosche) on 2025-04-02 07:49:21 in reply to 20 [link] [source]
I've used fossil mv quite a bit and learned the hard way early on: 1) always use fossil to rename &/or move files around
Question as someone pretty new it: could there be a heuristic to detect these cases for 1)? If in the same commit a file is removed and a file with the same checksum is added, that probably should be a rename. Maybe at least ask the user if they want to use rename first, before committing?
(22) By DB (ACB) on 2025-04-02 23:42:44 in reply to 21 [source]
If in the same commit a file is removed and a file with the same checksum is added, that probably should be a rename.
Excellent.
Another angle is this real world case from yesterday. I like to have some line items sort near each other because they are related, but they might not if their names are very different.
So I preface the names with the category on the far left.
At some point I had a long list of files. So I created a folder for that category, moved all the files into that folder, then removed that prefix from the front of the name.
- Bigfoo.md
- Foo2.md
- Kind1 Foofoo.md
- Kind1 Redfoo.md
- Kungfoo.md
- Simple Arm.md
- Simple Foo.md
- Simple Foot.md
Became
- Bigfoo.md
- Foo2.md
- Kind1/Foofoo.md
- Kind1/Redfoo.md
- Kungfoo.md
- Simple/Arm.md
- Simple/Foo.md
- Simple/Foot.md
Although I should admit I've also done some renaming that wasn't so simple like that. But generally I don't change much of the file name, just the order of some of the words in it.
Also, sometimes I have modified a file after renaming it and before committing the name change. So both the name and checksum would be different from the prior commit. So fossil would have to peer into files I guess, to attempt to match up MISSING and DELETED versioned files with ones it sees to ADD. Depending on how many changes the file(s) underwent, that could be very tricky.
(23) By Trevor (MelvaigT) on 2025-04-03 10:37:16 in reply to 11 [link] [source]
But tricky.
If mv
were to be made undo-able, do we consider the content of the file(s) part of the modified state or not? For example if I fossil mv a b
and then edit b
, should undo
restore the original content of a
? If we think it should, then that means redo
has to have access to the edited version of b
.
(24) By spindrift on 2025-04-03 11:09:39 in reply to 23 [link] [source]
This is a consideration for how most undo commands work though, isn't it?
It would revert to the original state of a presumably prior to the move, not move the new b back to the old name.
(25) By Andy Bradford (andybradford) on 2025-04-03 14:26:08 in reply to 24 [link] [source]
> This is a consideration for how most undo commands work though, isn't > it? But it kind of blurs the distinction between "undo" and "revert" in my mind. Fossil can already "revert" a "fossil mv" (as I demonstrated in a parallel thread). But just in case it wasn't seen: $ fossil mv OLDFILE NEWFILE RENAME OLDFILE NEWFILE $ fossil revert DELETE NEWFILE REVERT OLDFILE "fossil undo" is available to undo changes to the working checkout. $ fossil mv OLDFILE NEWFILE --hard RENAME OLDFILE NEWFILE MOVED_FILE /tmp/new/OLDFILE $ fossil revert DELETE NEWFILE REVERT OLDFILE "fossil undo" is available to undo changes to the working checkout. To Trevor's point, what happens if I mv the file AND edit the file? $ fossil mv OLDFILE NEWFILE --hard RENAME OLDFILE NEWFILE MOVED_FILE /tmp/new/OLDFILE $ echo $RANDOM >> NEWFILE $ md5 NEWFILE MD5 (NEWFILE) = f61d7cc41fa8bd5d738db42954b8ee7d $ fossil revert DELETE NEWFILE REVERT OLDFILE "fossil undo" is available to undo changes to the working checkout. The modified contents of NEWFILE are now lost, but if I realize that this has just happened, I can now issue "fossil undo" to restore my NEWFILE with my modifications. Sure, it will also restore the rename operation, but that's kind of what "undo" is for. $ fossil undo NEW NEWFILE DELETE OLDFILE $ md5 NEWFILE MD5 (NEWFILE) = f61d7cc41fa8bd5d738db42954b8ee7d Which raises the question in my mind, under what conditions is it appropriate to have an "undo" option available versus when should one rely on "revert"? Andy
(26) By Andy Bradford (andybradford) on 2025-04-03 16:22:37 in reply to 23 [link] [source]
> For example if I fossil mv a b and then edit b, should undo restore > the original content of a? After fossil has "stacked" an undo there are certain actions to the repository that will basically nullify the undo. This is documented in the help for "undo": https://www.fossil-scm.org/home/help/undo In particular it states: A single level of undo/redo is supported. The undo/redo stack is cleared by the commit and check-out commands. Other commands may or may not clear the undo stack. So, would "editing a file after mv" be considered something that "clears the stack"? Obviously there is no way for vi to clear the Fossil undo stack, so there might have to be something else to track the state. That being said, if "fossil mv|rm" were to get "undo" support basically it would mean that Fossil would replace whatever is currently in the "undo" stack with a new "undo" operation that would restore the the state to what it was just prior to running "fossil mv|rm". If you were then to edit a file, it could clear the stack and return an error because it would no longer be possible to undo, right? Just thinking out loud here. Andy
(27) By Martin Gagnon (mgagnon) on 2025-04-03 16:46:00 in reply to 26 [link] [source]
... Obviously there is no way for vi to clear ..
May be the undo command could issue a warning (or a kind of are you sure y/n prompt) if it detect that some file on the disk are different from what was saved on the undo stack ? So the user can take decision if he is willing loose the edit was done after the fossil mv
command ?
(also thinking out loud...)
(28) By Richard Hipp (drh) on 2025-04-03 17:06:11 in reply to 25 [link] [source]
"revert" takes you all the way back to the last commit. "undo" just takes you back one step.
(29) By matt w. (maphew) on 2025-04-03 20:42:36 in reply to 2 [link] [source]
For these reasons, I advocate that we change the default to on;
yes please