Closed sunn4room closed 1 year ago
A rename subcommand is very difficult to implement, which is why chezmoi doesn't yet have one. Some explanation:
When I want to rename a managed file, I always do this:
chezmoi forget xxx mv xxx new-xxx chezmoi add new-xxx
This isn't quite correct as it only works on the current machine. If you have another machine with xxx
already on it, then after you run chezmoi apply
you will end up with both xxx
and new-xxx
. chezmoi will ignore the existing xxx
(because you ran chezmoi forget xxx
, so chezmoi won't touch it), but will add new-xxx
(because you ran chezmoi add new-xxx
).
To robustly rename xxx
to new-xxx
, you need to chezmoi add new-xxx
add also ensure that xxx
is removed. You can ensure that xxx
is removed by either adding it to .chezmoiremove
or creating an empty xxx
file in your source state without the empty_
prefix (because chezmoi will remove empty files unless they have the empty_
prefix).
To implement a rename robustly, you not only have to cope with local renames, but also with the .chezmoiremove
and .chezmoiignore
files, both of which are templates and also support pattern matching.
So renaming xxx
to new-xxx
is not simple to implement, which is why you still have to do things manually.
Happy to hear ideas on how to implement a chezmoi mv
/chezmoi rename
command.
I find a file named '.chezmoistat.boltdb' in xdg config directory. If I'm right, this file record the status of applied files in a specific machine. When renamed a file in another machine, chezmoi can scan the applied files, and find the outdated files which is already not exists in source directory, then delete it at a right time. Is this idear useful?
Some dotfiles manager use symlink to sync dotfiles, but chezmoi use copy. It's a great idea. and it's meaningful to implement some useful features such as template and encrypt. But I think that .chezmoiremove
is a little fussy. Chezmoi use apply
to update specific dotfiles content to destination of local machine. It means that chezmoi has the right to manage the content of destination dotfiles. When the content changed, chezmoi should remind user to re-add
or apply
. But I cannot find a appropriate subcommand to release the right. Temporarily named release
, when run chezmoi release xxx
, chezmoi should delete the state in .chezmoistate.boltdb
( there is a subcommand chezmoi state
); When run chezmoi release -f xxx
, chezmoi should also delete the destination file.
After implement release
subcommand, it's natural to implement rename
subcommand. After renamed a file in another machine, chezmoi can release
the nonexisted files automatically.
One would need to have a record of things that were in state but are no longer in state, that weren’t simply forgotten (e.g., chezmoi forget
). With the sort of thing that you’re talking about, you could have a data loss situation:
chezmoi apply
on machine1 and machine2.chezmoi forget something
. This removes it from the chezmoi state and repo. You commit and push up the change.chezmoi forget something
, but instead do chezmoi apply
. With what you’ve identified, this looks like a remove, so chezmoi removes something
from machine2.I’m talking about deletion, but just like git, chezmoi does not have a concept of a rename, only delete and add. (Renames are heuristically determined.)
Terraform has a similar issue, in that you can rename something in your definitions that requires you to manually record the rename or you will end up destroying and creating your resources. There are two ways to do this: terraform state mv OLDNAME NEWNAME
or a moved block:
moved {
from = OLDNAME
to = NEWNAME
}
With moved
blocks, you can keep them around forever:
moved {
from = OLDNAME
to = NEWNAME
}
moved {
from = NEWNAME
to = NEWERNAME
}
moved {
from = NEWERNAME
to = NEWESTNAMEYET
}
chezmoi would need to implement such rename
rules, but heuristic determination won’t be the answer. (If you do a git mv OLDNAME NEWNAME
and then edit the file so that it is very different, instead of a rename
in git status
, you will see deleted OLDNAME
and added NEWNAME
.)
All this to say that (1) this isn’t easy, especially with multiple machines involved, (2) it requires explicit support to make possible, and (3) I don’t think that the effort expended on this would be worth the ~effort involved~ benefit received.
When I want to rename a managed file, I always do this:
It's a little fussy, and I cannot find a appropriate subcommand with
chezmoi help
, and there is no useful message in github repo issues. Any advice?