stow icon indicating copy to clipboard operation
stow copied to clipboard

New command line option `--orig` to rename conflicting files

Open lassik opened this issue 9 years ago • 10 comments

Hello!

Thank you for stow -- I'm enjoying it a lot. It has become the first tool that I install on a new machine after git. Also, I hope github is an OK channel for sending feature requests.

Here's my request: It'd be nice to have a new command line option --orig (or similar) to make backups of conflicting files in the target directory instead of failing on conflict. For example:

  • hosts => hosts.orig
  • ntp.conf => ntp.conf.orig
  • .bashrc => .bashrc.orig

I often use stow to link files from a git repo into $HOME or /etc, and Linux distributions ship with default configuration files in these locations that stow will trip over. The --adopt option does not solve my problem because I don't want to copy the OS default configs into my git repo - I want to do the opposite and overwrite the OS default configs (but keep backups of them).

Leaving each backup file in the same directory as the original and using a constant backup extension (.orig) has the nice effect that one can do e.g. find /etc -name "*.orig" to find all overwritten configs. Likewise, it's fairly easy to run diff to see changes from the OS defaults.

Here's a demonstration of what currently happens:

$ mkdir demo
$ mkdir -p demo/stow/test
$ touch demo/foo demo/stow/test/foo
$ tree demo --charset ascii
demo
|-- foo
`-- stow
    `-- test
        `-- foo

2 directories, 2 files
$ (cd demo/stow && stow test)
WARNING! stowing test would cause conflicts:
  * existing target is neither a link nor a directory: foo
All operations aborted.

This is what I would like to have:

$ (cd demo/stow && stow --orig -vv test)
...
RENAME: foo => foo.orig
LINK: foo => stow/test/foo
...
$ tree demo --charset ascii
demo
|-- foo -> stow/test/foo
|-- foo.orig
`-- stow
    `-- test
        `-- foo

2 directories, 3 files

Here's a succint description of the behavior that --orig would have, covering edge cases:

  • IF dst already exists THEN
    • IF dst.orig already exists THEN give up and stop with an error
    • ELSE rename dst to dst.orig(even if dst is a symlink, a directory, etc.)
      • IF the rename fails due to permissions etc. THEN give up and stop with an error

The option could also be named --backup or similar, but I personally like --orig because it's short and mnemonic (it reminds the user that the backup filename will have the extension .orig, which is also a de facto standard extension for such files).

Would you accept a feature like this into stow?

Kind regards, Lassi

lassik avatar Jun 30 '15 18:06 lassik

More sketching:

What if we instead moved the backup files into a designated backup directory that mirrors directory structure in the same way that stow packages do. E.g.

$ tree -a --charset ascii
.
|-- .git
|-- .gitignore
`-- my-configs
    `-- etc
        `-- ntp.conf
$ cat .gitignore
/defaults/
$ stow my-configs -vvt / --backupdir defaults
...
MKDIR: defaults       # because it didn't exist already
MKDIR: defaults/etc   # because it didn't exist already
COPY: /etc/ntp.conf => defaults/etc/ntp.conf  # or this could be a rename...
REMOVE: /etc/ntp.conf         # ...if file system boundaries are not crossed
LINK: etc/ntp.conf => /etc/ntp.conf
...
$ tree -a --charset ascii
.
|-- defaults
|   `-- etc
|       `-- ntp.conf
|-- .git
|-- .gitignore
`-- my-configs
    `-- etc
        `-- ntp.conf

If the user wanted to, they could also append a filename extension of their choice to all backup files. If they didn't give such an extension, nothing would be appended. E.g.:

$ stow my-configs -vvt / --backupext .orig
...
RENAME: /etc/ntp.conf => /etc/ntp.conf.orig
LINK: etc/ntp.conf => /etc/ntp.conf
...

It would also be possible to combine --backupdir and --backupext in a natural way:

$ stow my-configs -vvt / --backupdir defaults --backupext .orig
...
COPY: /etc/ntp.conf => defaults/etc/ntp.conf.orig
REMOVE: /etc/ntp.conf
LINK: etc/ntp.conf => /etc/ntp.conf
...

lassik avatar Jun 30 '15 19:06 lassik

Great work in outlining this, lassik! This feature would be reeeeally useful.

Deichscheich avatar Dec 10 '15 22:12 Deichscheich

:+1:

SyntaxColoring avatar Dec 11 '15 06:12 SyntaxColoring

Yes thanks, this is a good feature request. Please look at patch(1) for ideas on how to define options which control the algorithm for choosing where to back up to.

aspiers avatar Dec 11 '15 10:12 aspiers

Thanks for the interest!

Good tip on patch(1). The above proposed --backupdir and --backupext seem equivalent to patch's --prefix and --suffix, respectively. (Except that patch's --prefix need not be a directory if it doesn't end in a slash.)

patch's naming scheme support seems very comprehensive with the --basename-prefix and --version-control options (numbered backup files, etc.) in addition to the above. Do you think anyone would find these useful in stow's context? My personal intuition is that they would be over the top.

lassik avatar Dec 11 '15 21:12 lassik

Yeah, that seems like overkill.

SyntaxColoring avatar Dec 11 '15 23:12 SyntaxColoring

This would be a nice feature. Did it make it in?

sebastienbarre avatar Nov 23 '16 23:11 sebastienbarre

Nope, someone has to code it first ;-)

aspiers avatar Nov 24 '16 01:11 aspiers

Would be really cool if it would be possible to overwrite existing files.

astier avatar Jan 20 '19 11:01 astier

If someone badly needs this (like I do!) and can't wait for this to be merged into upstream, and is on Arch, you're welcome to my PKGBUILD in the meantime.

H3mul avatar Jun 01 '21 00:06 H3mul