Skip to content

Commit 0f2dcff

Browse files
authored
Merge pull request #525 from twpayne/add-template
Don't add files if template would be overwritten
2 parents 90c506b + a1caca6 commit 0f2dcff

File tree

8 files changed

+94
-60
lines changed

8 files changed

+94
-60
lines changed

cmd/add.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var addCmd = &cobra.Command{
2424
}
2525

2626
type addCmdConfig struct {
27+
force bool
2728
recursive bool
2829
prompt bool
2930
options chezmoi.AddOptions
@@ -35,6 +36,7 @@ func init() {
3536
persistentFlags := addCmd.PersistentFlags()
3637
persistentFlags.BoolVarP(&config.add.options.Empty, "empty", "e", false, "add empty files")
3738
persistentFlags.BoolVar(&config.add.options.Encrypt, "encrypt", false, "encrypt files")
39+
persistentFlags.BoolVarP(&config.add.force, "force", "f", false, "overwrite source state, even if template would be lost")
3840
persistentFlags.BoolVarP(&config.add.options.Exact, "exact", "x", false, "add directories exactly")
3941
persistentFlags.BoolVarP(&config.add.prompt, "prompt", "p", false, "prompt before adding")
4042
persistentFlags.BoolVarP(&config.add.recursive, "recursive", "r", false, "recurse in to subdirectories")
@@ -75,6 +77,16 @@ func (c *Config) runAddCmd(cmd *cobra.Command, args []string) (err error) {
7577
fmt.Fprintf(c.Stderr(), "warning: skipping file ignored by .chezmoiignore: %s\n", path)
7678
return nil
7779
}
80+
if !c.add.force {
81+
entry, err := ts.Get(c.fs, path)
82+
if err != nil && !os.IsNotExist(err) {
83+
return err
84+
}
85+
if file, ok := entry.(*chezmoi.File); ok && file.Template {
86+
fmt.Fprintf(c.Stderr(), "warning: skipping file generated by template, use --force to force: %s\n", path)
87+
return nil
88+
}
89+
}
7890
if c.add.prompt {
7991
choice, err := c.prompt(fmt.Sprintf("Add %s", path), "ynqa")
8092
if err != nil {
@@ -99,6 +111,16 @@ func (c *Config) runAddCmd(cmd *cobra.Command, args []string) (err error) {
99111
fmt.Fprintf(c.Stderr(), "warning: skipping file ignored by .chezmoiignore: %s\n", path)
100112
continue
101113
}
114+
if !c.add.force {
115+
entry, err := ts.Get(c.fs, path)
116+
if err != nil && !os.IsNotExist(err) {
117+
return err
118+
}
119+
if file, ok := entry.(*chezmoi.File); ok && file.Template {
120+
fmt.Fprintf(c.Stderr(), "warning: skipping file generated by template, use --force to force: %s\n", path)
121+
continue
122+
}
123+
}
102124
if c.add.prompt {
103125
choice, err := c.prompt(fmt.Sprintf("Add %s", path), "ynqa")
104126
if err != nil {

cmd/helps.gen.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

completions/chezmoi-completion.bash

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ _chezmoi_add()
277277
flags+=("--encrypt")
278278
flags+=("--exact")
279279
flags+=("-x")
280+
flags+=("--force")
281+
flags+=("-f")
280282
flags+=("--prompt")
281283
flags+=("-p")
282284
flags+=("--recursive")

completions/chezmoi.fish

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -s a -l aut
7474
complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -s e -l empty -d 'add empty files'
7575
complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -l encrypt -d 'encrypt files'
7676
complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -s x -l exact -d 'add directories exactly'
77+
complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -s f -l force -d 'overwrite source state, even if template would be lost'
7778
complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -s p -l prompt -d 'prompt before adding'
7879
complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -s r -l recursive -d 'recurse in to subdirectories'
7980
complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -s T -l template -d 'add files as templates'

completions/chezmoi.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ function _chezmoi_add {
143143
'(-e --empty)'{-e,--empty}'[add empty files]' \
144144
'--encrypt[encrypt files]' \
145145
'(-x --exact)'{-x,--exact}'[add directories exactly]' \
146+
'(-f --force)'{-f,--force}'[overwrite source state, even if template would be lost]' \
146147
'(-p --prompt)'{-p,--prompt}'[prompt before adding]' \
147148
'(-r --recursive)'{-r,--recursive}'[recurse in to subdirectories]' \
148149
'(-T --template)'{-T,--template}'[add files as templates]' \

docs/CHANGES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<!--- toc --->
44
* [Upcoming](#upcoming)
5-
* [`gpgRecipient` config variable changing to `gpg.recipient`](#gpgrecipient-config-variable-changing-to-gpgrecipient)
5+
* [gpgRecipient config variable changing to gpg.recipient](#gpgrecipient-config-variable-changing-to-gpgrecipient)
66

77
## Upcoming
88

docs/FAQ.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22

33
<!--- toc --->
44
* [How can I quickly check for problems with chezmoi on my machine?](#how-can-i-quickly-check-for-problems-with-chezmoi-on-my-machine)
5-
* [What are the consequences of "bare" modifications to the target files? If my `.zshrc` is managed by chezmoi and I edit `~/.zshrc` without using `chezmoi edit`, what happens?](#what-are-the-consequences-of-bare-modifications-to-the-target-files-if-my-zshrc-is-managed-by-chezmoi-and-i-edit-zshrc-without-using-chezmoi-edit-what-happens)
5+
* [What are the consequences of &quot;bare&quot; modifications to the target files? If my .zshrc is managed by chezmoi and I edit ~/.zshrc without using chezmoi edit, what happens?](#what-are-the-consequences-of-quotbarequot-modifications-to-the-target-files-if-my-zshrc-is-managed-by-chezmoi-and-i-edit-zshrc-without-using-chezmoi-edit-what-happens)
66
* [How can I tell what dotfiles in my home directory aren't managed by chezmoi? Is there an easy way to have chezmoi manage a subset of them?](#how-can-i-tell-what-dotfiles-in-my-home-directory-arent-managed-by-chezmoi-is-there-an-easy-way-to-have-chezmoi-manage-a-subset-of-them)
77
* [If there's a mechanism in place for the above, is there also a way to tell chezmoi to ignore specific files or groups of files (e.g. by directory name or by glob)?](#if-theres-a-mechanism-in-place-for-the-above-is-there-also-a-way-to-tell-chezmoi-to-ignore-specific-files-or-groups-of-files-eg-by-directory-name-or-by-glob)
8-
* [If the target already exists, but is "behind" the source, can chezmoi be configured to preserve the target version before replacing it with one derived from the source?](#if-the-target-already-exists-but-is-behind-the-source-can-chezmoi-be-configured-to-preserve-the-target-version-before-replacing-it-with-one-derived-from-the-source)
8+
* [If the target already exists, but is &quot;behind&quot; the source, can chezmoi be configured to preserve the target version before replacing it with one derived from the source?](#if-the-target-already-exists-but-is-quotbehindquot-the-source-can-chezmoi-be-configured-to-preserve-the-target-version-before-replacing-it-with-one-derived-from-the-source)
99
* [How do I only run a script when a file has changed?](#how-do-i-only-run-a-script-when-a-file-has-changed)
1010
* [I've made changes to both the destination state and the source state that I want to keep. How can I keep them both?](#ive-made-changes-to-both-the-destination-state-and-the-source-state-that-i-want-to-keep-how-can-i-keep-them-both)
1111
* [chezmoi's source file naming system cannot handle all possible filenames](#chezmois-source-file-naming-system-cannot-handle-all-possible-filenames)
1212
* [gpg encryption fails. What could be wrong?](#gpg-encryption-fails-what-could-be-wrong)
1313
* [I'm getting errors trying to build chezmoi from source](#im-getting-errors-trying-to-build-chezmoi-from-source)
1414
* [What inspired chezmoi?](#what-inspired-chezmoi)
1515
* [Can I use chezmoi outside my home directory?](#can-i-use-chezmoi-outside-my-home-directory)
16-
* [Where does the name "chezmoi" come from?](#where-does-the-name-chezmoi-come-from)
16+
* [Where does the name &quot;chezmoi&quot; come from?](#where-does-the-name-quotchezmoiquot-come-from)
1717
* [What other questions have been asked about chezmoi?](#what-other-questions-have-been-asked-about-chezmoi)
1818
* [Where do I ask a question that isn't answered here?](#where-do-i-ask-a-question-that-isnt-answered-here)
1919

docs/REFERENCE.md

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,71 +5,71 @@ Manage your dotfiles securely across multiple machines.
55
<!--- toc --->
66
* [Concepts](#concepts)
77
* [Global command line flags](#global-command-line-flags)
8-
* [`--color` *value*](#--color-value)
9-
* [`-c`, `--config` *filename*](#-c---config-filename)
10-
* [`--debug`](#--debug)
11-
* [`-D`, `--destination` *directory*](#-d---destination-directory)
12-
* [`-f`, `--follow`](#-f---follow)
13-
* [`-n`, `--dry-run`](#-n---dry-run)
14-
* [`-h`, `--help`](#-h---help)
15-
* [`-r`. `--remove`](#-r---remove)
16-
* [`-S`, `--source` *directory*](#-s---source-directory)
17-
* [`-v`, `--verbose`](#-v---verbose)
18-
* [`--version`](#--version)
8+
* [--color value](#--color-value)
9+
* [-c, --config filename](#-c---config-filename)
10+
* [--debug](#--debug)
11+
* [-D, --destination directory](#-d---destination-directory)
12+
* [-f, --follow](#-f---follow)
13+
* [-n, --dry-run](#-n---dry-run)
14+
* [-h, --help](#-h---help)
15+
* [-r. --remove](#-r---remove)
16+
* [-S, --source directory](#-s---source-directory)
17+
* [-v, --verbose](#-v---verbose)
18+
* [--version](#--version)
1919
* [Configuration file](#configuration-file)
2020
* [Configuration variables](#configuration-variables)
2121
* [Source state attributes](#source-state-attributes)
2222
* [Special files and directories](#special-files-and-directories)
23-
* [`.chezmoi.<format>.tmpl`](#chezmoiformattmpl)
24-
* [`.chezmoiignore`](#chezmoiignore)
25-
* [`.chezmoiremove`](#chezmoiremove)
26-
* [`.chezmoitemplates`](#chezmoitemplates)
27-
* [`.chezmoiversion`](#chezmoiversion)
23+
* [.chezmoi.&lt;format&gt;.tmpl](#chezmoiltformatgttmpl)
24+
* [.chezmoiignore](#chezmoiignore)
25+
* [.chezmoiremove](#chezmoiremove)
26+
* [.chezmoitemplates](#chezmoitemplates)
27+
* [.chezmoiversion](#chezmoiversion)
2828
* [Commands](#commands)
29-
* [`add` *targets*](#add-targets)
30-
* [`apply` [*targets*]](#apply-targets)
31-
* [`archive`](#archive)
32-
* [`cat` targets](#cat-targets)
33-
* [`cd`](#cd)
34-
* [`chattr` *attributes* *targets*](#chattr-attributes-targets)
35-
* [`completion` *shell*](#completion-shell)
36-
* [`data`](#data)
37-
* [`diff` [*targets*]](#diff-targets)
38-
* [`docs` [*regexp*]](#docs-regexp)
39-
* [`doctor`](#doctor)
40-
* [`dump` [*targets*]](#dump-targets)
41-
* [`edit` [*targets*]](#edit-targets)
42-
* [`edit-config`](#edit-config)
43-
* [`forget` *targets*](#forget-targets)
44-
* [`help` *command*](#help-command)
45-
* [`init` [*repo*]](#init-repo)
46-
* [`import` *filename*](#import-filename)
47-
* [`merge` *targets*](#merge-targets)
48-
* [`remove` *targets*](#remove-targets)
49-
* [`secret`](#secret)
50-
* [`source` [*args*]](#source-args)
51-
* [`source-path` [*targets*]](#source-path-targets)
52-
* [`unmanaged`](#unmanaged)
53-
* [`update`](#update)
54-
* [`upgrade`](#upgrade)
55-
* [`verify` [*targets*]](#verify-targets)
29+
* [add targets](#add-targets)
30+
* [apply [targets]](#apply-targets)
31+
* [archive](#archive)
32+
* [cat targets](#cat-targets)
33+
* [cd](#cd)
34+
* [chattr attributes targets](#chattr-attributes-targets)
35+
* [completion shell](#completion-shell)
36+
* [data](#data)
37+
* [diff [targets]](#diff-targets)
38+
* [docs [regexp]](#docs-regexp)
39+
* [doctor](#doctor)
40+
* [dump [targets]](#dump-targets)
41+
* [edit [targets]](#edit-targets)
42+
* [edit-config](#edit-config)
43+
* [forget targets](#forget-targets)
44+
* [help command](#help-command)
45+
* [init [repo]](#init-repo)
46+
* [import filename](#import-filename)
47+
* [merge targets](#merge-targets)
48+
* [remove targets](#remove-targets)
49+
* [secret](#secret)
50+
* [source [args]](#source-args)
51+
* [source-path [targets]](#source-path-targets)
52+
* [unmanaged](#unmanaged)
53+
* [update](#update)
54+
* [upgrade](#upgrade)
55+
* [verify [targets]](#verify-targets)
5656
* [Editor configuration](#editor-configuration)
5757
* [Umask configuration](#umask-configuration)
5858
* [Template variables](#template-variables)
5959
* [Template functions](#template-functions)
60-
* [`bitwarden` [*args*]](#bitwarden-args)
61-
* [`gopass` *gopass-name*](#gopass-gopass-name)
62-
* [`keepassxc` *entry*](#keepassxc-entry)
63-
* [`keepassxcAttribute` *entry* *attribute*](#keepassxcattribute-entry-attribute)
64-
* [`keyring` *service* *user*](#keyring-service-user)
65-
* [`lastpass` *id*](#lastpass-id)
66-
* [`onepassword` *uuid*](#onepassword-uuid)
67-
* [`onepasswordDocument` *uuid*](#onepassworddocument-uuid)
68-
* [`pass` *pass-name*](#pass-pass-name)
69-
* [`promptString` *prompt*](#promptstring-prompt)
70-
* [`secret` [*args*]](#secret-args)
71-
* [`secretJSON` [*args*]](#secretjson-args)
72-
* [`vault` *key*](#vault-key)
60+
* [bitwarden [args]](#bitwarden-args)
61+
* [gopass gopass-name](#gopass-gopass-name)
62+
* [keepassxc entry](#keepassxc-entry)
63+
* [keepassxcAttribute entry attribute](#keepassxcattribute-entry-attribute)
64+
* [keyring service user](#keyring-service-user)
65+
* [lastpass id](#lastpass-id)
66+
* [onepassword uuid](#onepassword-uuid)
67+
* [onepasswordDocument uuid](#onepassworddocument-uuid)
68+
* [pass pass-name](#pass-pass-name)
69+
* [promptString prompt](#promptstring-prompt)
70+
* [secret [args]](#secret-args)
71+
* [secretJSON [args]](#secretjson-args)
72+
* [vault key](#vault-key)
7373

7474
## Concepts
7575

@@ -322,6 +322,10 @@ directory. The `add` command accepts additional flags:
322322

323323
Set the `empty` attribute on added files.
324324

325+
#### `-f`, `--force`
326+
327+
Add *targets*, even if doing so would cause a source template to be overwritten.
328+
325329
#### `-x`, `--exact`
326330

327331
Set the `exact` attribute on added directories.

0 commit comments

Comments
 (0)