Fossil User Forum

RFC: Change the default for ”mv-rm-files” to ”on”
Login

RFC: Change the default for ”mv-rm-files” to ”on”

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

(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

(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.

(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.)

(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 ?

(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.

(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

(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).

(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

(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.

(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...)

(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!

(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

(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.

(17) By DB (ACB) on 2025-04-01 23:21:29 in reply to 1.1 [link] [source]

Glad to see it changed. :-)

(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.