Repository: twpayne/chezmoi
Pull request #430 (2019-09-17 01:14:29)

Make --follow a global option


Patch:
diff --git a/cmd/add.go b/cmd/add.go
index d5894067d..c91b30475 100644
--- a/cmd/add.go
+++ b/cmd/add.go
@@ -35,7 +35,6 @@ func init() {
 	persistentFlags.BoolVarP(&config.add.options.Empty, "empty", "e", false, "add empty files")
 	persistentFlags.BoolVar(&config.add.options.Encrypt, "encrypt", false, "encrypt files")
 	persistentFlags.BoolVarP(&config.add.options.Exact, "exact", "x", false, "add directories exactly")
-	persistentFlags.BoolVarP(&config.add.options.Follow, "follow", "f", false, "follow last symlink")
 	persistentFlags.BoolVarP(&config.add.prompt, "prompt", "p", false, "prompt before adding")
 	persistentFlags.BoolVarP(&config.add.recursive, "recursive", "r", false, "recurse in to subdirectories")
 	persistentFlags.BoolVarP(&config.add.options.Template, "template", "T", false, "add files as templates")
@@ -90,7 +89,7 @@ func (c *Config) runAddCmd(fs vfs.FS, args []string) (err error) {
 						c.add.prompt = false
 					}
 				}
-				return ts.Add(fs, c.add.options, path, info, mutator)
+				return ts.Add(fs, c.add.options, path, info, c.Follow, mutator)
 			}); err != nil {
 				return err
 			}
@@ -113,7 +112,7 @@ func (c *Config) runAddCmd(fs vfs.FS, args []string) (err error) {
 					c.add.prompt = false
 				}
 			}
-			if err := ts.Add(fs, c.add.options, path, nil, mutator); err != nil {
+			if err := ts.Add(fs, c.add.options, path, nil, c.Follow, mutator); err != nil {
 				return err
 			}
 		}
diff --git a/cmd/config.go b/cmd/config.go
index aeb4c9117..111c60846 100644
--- a/cmd/config.go
+++ b/cmd/config.go
@@ -38,6 +38,7 @@ type Config struct {
 	DestDir           string
 	Umask             permValue
 	DryRun            bool
+	Follow            bool
 	Remove            bool
 	Verbose           bool
 	Color             string
@@ -148,14 +149,14 @@ func (c *Config) applyArgs(fs vfs.FS, args []string, mutator chezmoi.Mutator) er
 		Verbose:           c.Verbose,
 	}
 	if len(args) == 0 {
-		return ts.Apply(fs, mutator, applyOptions)
+		return ts.Apply(fs, mutator, c.Follow, applyOptions)
 	}
 	entries, err := c.getEntries(fs, ts, args)
 	if err != nil {
 		return err
 	}
 	for _, entry := range entries {
-		if err := entry.Apply(fs, mutator, applyOptions); err != nil {
+		if err := entry.Apply(fs, mutator, c.Follow, applyOptions); err != nil {
 			return err
 		}
 	}
diff --git a/cmd/edit.go b/cmd/edit.go
index fe707202a..2ed862174 100644
--- a/cmd/edit.go
+++ b/cmd/edit.go
@@ -173,7 +173,7 @@ func (c *Config) runEditCmd(fs vfs.FS, args []string) error {
 		if c.edit.diff {
 			mutator = chezmoi.NewLoggingMutator(c.Stdout(), mutator, c.colored)
 		}
-		if err := entry.Apply(readOnlyFS, mutator, &applyOptions); err != nil {
+		if err := entry.Apply(readOnlyFS, mutator, c.Follow, &applyOptions); err != nil {
 			return err
 		}
 		if c.edit.apply && anyMutator.Mutated() {
@@ -192,7 +192,7 @@ func (c *Config) runEditCmd(fs vfs.FS, args []string) error {
 					c.edit.prompt = false
 				}
 			}
-			if err := entry.Apply(readOnlyFS, applyMutator, &applyOptions); err != nil {
+			if err := entry.Apply(readOnlyFS, applyMutator, c.Follow, &applyOptions); err != nil {
 				return err
 			}
 		}
diff --git a/cmd/helps.gen.go b/cmd/helps.gen.go
index 07a90c84b..4fdaf0675 100644
--- a/cmd/helps.gen.go
+++ b/cmd/helps.gen.go
@@ -22,12 +22,6 @@ var helps = map[string]help{
 			"\n" +
 			"Set the \"exact\" attribute on added directories.\n" +
 			"\n" +
-			"\"-f\", \"--follow\"\n" +
-			"\n" +
-			"If the target is a symlink, add what it points to, rather than the symlink\n" +
-			"itself. This is useful when migrating your dotfiles from a system that uses\n" +
-			"symlinks.\n" +
-			"\n" +
 			"\"-p\", \"--prompt\"\n" +
 			"\n" +
 			"Interactively prompt before adding each file.\n" +
diff --git a/cmd/root.go b/cmd/root.go
index 470852939..b3ac9a504 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -74,6 +74,9 @@ func init() {
 	persistentFlags.BoolVarP(&config.DryRun, "dry-run", "n", false, "dry run")
 	_ = viper.BindPFlag("dry-run", persistentFlags.Lookup("dry-run"))
 
+	persistentFlags.BoolVar(&config.Follow, "follow", false, "follow symlinks")
+	_ = viper.BindPFlag("follow", persistentFlags.Lookup("follow"))
+
 	persistentFlags.BoolVar(&config.Remove, "remove", false, "remove targets")
 	_ = viper.BindPFlag("remove", persistentFlags.Lookup("remove"))
 
diff --git a/completions/chezmoi-completion.bash b/completions/chezmoi-completion.bash
index 6f44a1a68..912cb1f6b 100644
--- a/completions/chezmoi-completion.bash
+++ b/completions/chezmoi-completion.bash
@@ -271,8 +271,6 @@ _chezmoi_add()
     flags+=("--encrypt")
     flags+=("--exact")
     flags+=("-x")
-    flags+=("--follow")
-    flags+=("-f")
     flags+=("--prompt")
     flags+=("-p")
     flags+=("--recursive")
@@ -289,6 +287,7 @@ _chezmoi_add()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -325,6 +324,7 @@ _chezmoi_apply()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -361,6 +361,7 @@ _chezmoi_archive()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -397,6 +398,7 @@ _chezmoi_cat()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -433,6 +435,7 @@ _chezmoi_cd()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -469,6 +472,7 @@ _chezmoi_chattr()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -508,6 +512,7 @@ _chezmoi_completion()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -550,6 +555,7 @@ _chezmoi_data()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -586,6 +592,7 @@ _chezmoi_diff()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -622,6 +629,7 @@ _chezmoi_docs()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -658,6 +666,7 @@ _chezmoi_doctor()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -699,6 +708,7 @@ _chezmoi_dump()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -741,6 +751,7 @@ _chezmoi_edit()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -777,6 +788,7 @@ _chezmoi_edit-config()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -813,6 +825,7 @@ _chezmoi_forget()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -855,6 +868,7 @@ _chezmoi_import()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -892,6 +906,7 @@ _chezmoi_init()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -928,6 +943,7 @@ _chezmoi_merge()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -966,6 +982,7 @@ _chezmoi_remove()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1002,6 +1019,7 @@ _chezmoi_secret_bitwarden()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1038,6 +1056,7 @@ _chezmoi_secret_generic()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1074,6 +1093,7 @@ _chezmoi_secret_keepassxc()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1110,6 +1130,7 @@ _chezmoi_secret_keyring_get()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--service=")
     two_word_flags+=("--service")
@@ -1152,6 +1173,7 @@ _chezmoi_secret_keyring_set()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--service=")
     two_word_flags+=("--service")
@@ -1198,6 +1220,7 @@ _chezmoi_secret_keyring()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1236,6 +1259,7 @@ _chezmoi_secret_lastpass()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1272,6 +1296,7 @@ _chezmoi_secret_onepassword()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1308,6 +1333,7 @@ _chezmoi_secret_pass()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1344,6 +1370,7 @@ _chezmoi_secret_vault()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1388,6 +1415,7 @@ _chezmoi_secret()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1424,6 +1452,7 @@ _chezmoi_source()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1460,6 +1489,7 @@ _chezmoi_source-path()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1496,6 +1526,7 @@ _chezmoi_unmanaged()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1534,6 +1565,7 @@ _chezmoi_update()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1581,6 +1613,7 @@ _chezmoi_upgrade()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1617,6 +1650,7 @@ _chezmoi_verify()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
@@ -1691,6 +1725,7 @@ _chezmoi_root_command()
     two_word_flags+=("-D")
     flags+=("--dry-run")
     flags+=("-n")
+    flags+=("--follow")
     flags+=("--remove")
     flags+=("--source=")
     two_word_flags+=("--source")
diff --git a/completions/chezmoi.fish b/completions/chezmoi.fish
index 5d6f9ced1..6d03ddbf6 100644
--- a/completions/chezmoi.fish
+++ b/completions/chezmoi.fish
@@ -65,6 +65,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand' -r  -l color -d 'colori
 complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_no_subcommand'  -s v -l verbose -d 'verbose'
@@ -72,7 +73,6 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s a -l aut
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s e -l empty -d 'add empty files'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'   -l encrypt -d 'encrypt files'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s x -l exact -d 'add directories exactly'
-complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s f -l follow -d 'follow last symlink'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s p -l prompt -d 'prompt before adding'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s r -l recursive -d 'recurse in to subdirectories'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s T -l template -d 'add files as templates'
@@ -80,6 +80,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -r  -l color
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path add'  -s v -l verbose -d 'verbose'
@@ -87,6 +88,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply' -r  -l col
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path apply'  -s v -l verbose -d 'verbose'
@@ -94,6 +96,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive' -r  -l c
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path archive'  -s v -l verbose -d 'verbose'
@@ -101,6 +104,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat' -r  -l color
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cat'  -s v -l verbose -d 'verbose'
@@ -108,6 +112,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd' -r  -l color
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path cd'  -s v -l verbose -d 'verbose'
@@ -115,6 +120,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path chattr'  -s v -l verbose -d 'verbose'
@@ -126,6 +132,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion' -r  -
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path completion'  -s v -l verbose -d 'verbose'
@@ -134,6 +141,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data' -r  -l colo
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path data'  -s v -l verbose -d 'verbose'
@@ -141,6 +149,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff' -r  -l colo
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path diff'  -s v -l verbose -d 'verbose'
@@ -148,6 +157,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs' -r  -l colo
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path docs'  -s v -l verbose -d 'verbose'
@@ -155,6 +165,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path doctor'  -s v -l verbose -d 'verbose'
@@ -164,6 +175,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump' -r  -l colo
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path dump'  -s v -l verbose -d 'verbose'
@@ -174,6 +186,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit' -r  -l colo
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit'  -s v -l verbose -d 'verbose'
@@ -181,6 +194,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config' -r
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path edit-config'  -s v -l verbose -d 'verbose'
@@ -188,6 +202,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path forget'  -s v -l verbose -d 'verbose'
@@ -198,6 +213,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path import'  -s v -l verbose -d 'verbose'
@@ -206,6 +222,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init' -r  -l colo
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path init'  -s v -l verbose -d 'verbose'
@@ -213,6 +230,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge' -r  -l col
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path merge'  -s v -l verbose -d 'verbose'
@@ -221,6 +239,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path remove'  -s v -l verbose -d 'verbose'
@@ -236,6 +255,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret'  -s v -l verbose -d 'verbose'
@@ -243,6 +263,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret bitwarden'  -s v -l verbose -d 'verbose'
@@ -250,6 +271,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic' -
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret generic'  -s v -l verbose -d 'verbose'
@@ -257,6 +279,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keepassxc'  -s v -l verbose -d 'verbose'
@@ -268,6 +291,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring' -
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring'  -s v -l verbose -d 'verbose'
@@ -275,6 +299,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring ge
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring get' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring get' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring get'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring get'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring get'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring get' -r  -l service -d 'service'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring get' -r -s S -l source -d 'source directory'
@@ -285,6 +310,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring se
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring set' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring set' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring set'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring set'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring set'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring set' -r  -l service -d 'service'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret keyring set' -r -s S -l source -d 'source directory'
@@ -294,6 +320,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret lastpass'  -s v -l verbose -d 'verbose'
@@ -301,6 +328,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepasswor
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepassword' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepassword' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepassword'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepassword'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepassword'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepassword' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret onepassword'  -s v -l verbose -d 'verbose'
@@ -308,6 +336,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass' -r
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret pass'  -s v -l verbose -d 'verbose'
@@ -315,6 +344,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault' -r
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path secret vault'  -s v -l verbose -d 'verbose'
@@ -322,6 +352,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source'  -s v -l verbose -d 'verbose'
@@ -329,6 +360,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path' -r
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path source-path'  -s v -l verbose -d 'verbose'
@@ -336,6 +368,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged' -r  -l
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path unmanaged'  -s v -l verbose -d 'verbose'
@@ -344,6 +377,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path update'  -s v -l verbose -d 'verbose'
@@ -355,6 +389,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade' -r  -l c
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path upgrade'  -s v -l verbose -d 'verbose'
@@ -362,6 +397,7 @@ complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify' -r  -l co
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify' -r -s c -l config -d 'config file'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify' -r -s D -l destination -d 'destination directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify'  -s n -l dry-run -d 'dry run'
+complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify'   -l follow -d 'follow symlinks'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify'   -l remove -d 'remove targets'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify' -r -s S -l source -d 'source directory'
 complete -c chezmoi -f -n '__fish_chezmoi_seen_subcommand_path verify'  -s v -l verbose -d 'verbose'
diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md
index 357a6b00a..8a9023d78 100644
--- a/docs/REFERENCE.md
+++ b/docs/REFERENCE.md
@@ -7,6 +7,7 @@ Manage your dotfiles securely across multiple machines.
   * [`--color` *value*](#--color-value)
   * [`-c`, `--config` *filename*](#-c---config-filename)
   * [`-D`, `--destination` *directory*](#-d---destination-directory)
+  * [`-f`, `--follow`](#-f---follow)
   * [`-n`, `--dry-run`](#-n---dry-run)
   * [`-h`, `--help`](#-h---help)
   * [`-r`. `--remove`](#-r---remove)
@@ -107,6 +108,11 @@ Read the configuration from *filename*.
 
 Use *directory* as the destination directory.
 
+### `-f`, `--follow`
+
+If the last part of a target is a symlink, deal with what the symlink
+references, rather than the symlink itself.
+
 ### `-n`, `--dry-run`
 
 Set dry run mode. In dry run mode, the destination directory is never modified.
@@ -156,6 +162,7 @@ The following configuration variables are available:
 | `data`                  | any      | *none*                    | Template data                       |
 | `destDir`               | string   | `~`                       | Destination directory               |
 | `dryRun`                | bool     | `false`                   | Dry run mode                        |
+| `follow`                | bool     | `false`                   | Follow symlinks                     |
 | `genericSecret.command` | string   | *none*                    | Generic secret command              |
 | `gpg.recipient`         | string   | *none*                    | GPG recipient                       |
 | `gpg.symmetric`         | bool     | `false`                   | Use symmetric GPG encryption        |
@@ -308,12 +315,6 @@ Set the `empty` attribute on added files.
 
 Set the `exact` attribute on added directories.
 
-#### `-f`, `--follow`
-
-If the target is a symlink, add what it points to, rather than the symlink
-itself. This is useful when migrating your dotfiles from a system that uses
-symlinks.
-
 #### `-p`, `--prompt`
 
 Interactively prompt before adding each file.
diff --git a/lib/chezmoi/chezmoi.go b/lib/chezmoi/chezmoi.go
index 9d06c86ec..2be0146f4 100644
--- a/lib/chezmoi/chezmoi.go
+++ b/lib/chezmoi/chezmoi.go
@@ -48,7 +48,7 @@ type ApplyOptions struct {
 
 // An Entry is either a Dir, a File, or a Symlink.
 type Entry interface {
-	Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) error
+	Apply(fs vfs.FS, mutator Mutator, follow bool, applyOptions *ApplyOptions) error
 	ConcreteValue(destDir string, ignore func(string) bool, sourceDir string, umask os.FileMode, recursive bool) (interface{}, error)
 	Evaluate(ignore func(string) bool) error
 	SourceName() string
diff --git a/lib/chezmoi/dir.go b/lib/chezmoi/dir.go
index c1aeff3c2..c695d6bfd 100644
--- a/lib/chezmoi/dir.go
+++ b/lib/chezmoi/dir.go
@@ -86,12 +86,18 @@ func newDir(sourceName string, targetName string, exact bool, perm os.FileMode)
 }
 
 // Apply ensures that destDir in fs matches d.
-func (d *Dir) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) error {
+func (d *Dir) Apply(fs vfs.FS, mutator Mutator, follow bool, applyOptions *ApplyOptions) error {
 	if applyOptions.Ignore(d.targetName) {
 		return nil
 	}
 	targetPath := filepath.Join(applyOptions.DestDir, d.targetName)
-	info, err := fs.Lstat(targetPath)
+	var info os.FileInfo
+	var err error
+	if follow {
+		info, err = fs.Stat(targetPath)
+	} else {
+		info, err = fs.Lstat(targetPath)
+	}
 	switch {
 	case err == nil && info.IsDir():
 		if info.Mode().Perm() != d.Perm&^applyOptions.Umask {
@@ -112,7 +118,7 @@ func (d *Dir) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) erro
 		return err
 	}
 	for _, entryName := range sortedEntryNames(d.Entries) {
-		if err := d.Entries[entryName].Apply(fs, mutator, applyOptions); err != nil {
+		if err := d.Entries[entryName].Apply(fs, mutator, follow, applyOptions); err != nil {
 			return err
 		}
 	}
diff --git a/lib/chezmoi/file.go b/lib/chezmoi/file.go
index 5413fa68f..1a02429ca 100644
--- a/lib/chezmoi/file.go
+++ b/lib/chezmoi/file.go
@@ -126,7 +126,7 @@ func (fa FileAttributes) SourceName() string {
 }
 
 // Apply ensures that the state of targetPath in fs matches f.
-func (f *File) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) error {
+func (f *File) Apply(fs vfs.FS, mutator Mutator, follow bool, applyOptions *ApplyOptions) error {
 	if applyOptions.Ignore(f.targetName) {
 		return nil
 	}
@@ -135,7 +135,12 @@ func (f *File) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) err
 		return err
 	}
 	targetPath := filepath.Join(applyOptions.DestDir, f.targetName)
-	info, err := fs.Lstat(targetPath)
+	var info os.FileInfo
+	if follow {
+		info, err = fs.Stat(targetPath)
+	} else {
+		info, err = fs.Lstat(targetPath)
+	}
 	var currData []byte
 	switch {
 	case err == nil && info.Mode().IsRegular():
diff --git a/lib/chezmoi/script.go b/lib/chezmoi/script.go
index 69d6d4a03..2e86b5d42 100644
--- a/lib/chezmoi/script.go
+++ b/lib/chezmoi/script.go
@@ -86,7 +86,7 @@ func (sa ScriptAttributes) SourceName() string {
 }
 
 // Apply runs s.
-func (s *Script) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) error {
+func (s *Script) Apply(fs vfs.FS, mutator Mutator, follow bool, applyOptions *ApplyOptions) error {
 	if applyOptions.Ignore(s.targetName) {
 		return nil
 	}
diff --git a/lib/chezmoi/symlink.go b/lib/chezmoi/symlink.go
index 9c0bb17c6..e9c3af117 100644
--- a/lib/chezmoi/symlink.go
+++ b/lib/chezmoi/symlink.go
@@ -27,7 +27,7 @@ type symlinkConcreteValue struct {
 }
 
 // Apply ensures that the state of s's target in fs matches s.
-func (s *Symlink) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) error {
+func (s *Symlink) Apply(fs vfs.FS, mutator Mutator, follow bool, applyOptions *ApplyOptions) error {
 	if applyOptions.Ignore(s.targetName) {
 		return nil
 	}
@@ -36,7 +36,12 @@ func (s *Symlink) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions)
 		return err
 	}
 	targetPath := filepath.Join(applyOptions.DestDir, s.targetName)
-	info, err := fs.Lstat(targetPath)
+	var info os.FileInfo
+	if follow {
+		info, err = fs.Stat(targetPath)
+	} else {
+		info, err = fs.Lstat(targetPath)
+	}
 	switch {
 	case err == nil && info.Mode()&os.ModeType == os.ModeSymlink:
 		currentTarget, err := fs.Readlink(targetPath)
diff --git a/lib/chezmoi/targetstate.go b/lib/chezmoi/targetstate.go
index a44975486..6162f6f92 100644
--- a/lib/chezmoi/targetstate.go
+++ b/lib/chezmoi/targetstate.go
@@ -29,7 +29,6 @@ type AddOptions struct {
 	Empty        bool
 	Encrypt      bool
 	Exact        bool
-	Follow       bool
 	Template     bool
 	AutoTemplate bool
 }
@@ -77,7 +76,7 @@ func NewTargetState(destDir string, umask os.FileMode, sourceDir string, data ma
 }
 
 // Add adds a new target to ts.
-func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string, info os.FileInfo, mutator Mutator) error {
+func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string, info os.FileInfo, follow bool, mutator Mutator) error {
 	contains, err := vfs.Contains(fs, targetPath, ts.DestDir)
 	if err != nil {
 		return err
@@ -91,7 +90,7 @@ func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string,
 	}
 	if info == nil {
 		var err error
-		if addOptions.Follow {
+		if follow {
 			info, err = fs.Stat(targetPath)
 		} else {
 			info, err = fs.Lstat(targetPath)
@@ -99,7 +98,7 @@ func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string,
 		if err != nil {
 			return err
 		}
-	} else if addOptions.Follow && info.Mode()&os.ModeType == os.ModeSymlink {
+	} else if follow && info.Mode()&os.ModeType == os.ModeSymlink {
 		info, err = fs.Stat(targetPath)
 		if err != nil {
 			return err
@@ -115,7 +114,7 @@ func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string,
 			return err
 		}
 		if parentEntry == nil {
-			if err := ts.Add(fs, addOptions, filepath.Join(ts.DestDir, parentDirName), nil, mutator); err != nil {
+			if err := ts.Add(fs, addOptions, filepath.Join(ts.DestDir, parentDirName), nil, follow, mutator); err != nil {
 				return err
 			}
 			parentEntry, err = ts.findEntry(parentDirName)
@@ -184,7 +183,7 @@ func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string,
 }
 
 // Apply ensures that ts.DestDir in fs matches ts.
-func (ts *TargetState) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOptions) error {
+func (ts *TargetState) Apply(fs vfs.FS, mutator Mutator, follow bool, applyOptions *ApplyOptions) error {
 	if applyOptions.Remove {
 		// Build a set of targets to remove.
 		targetsToRemove := make(map[string]struct{})
@@ -229,7 +228,7 @@ func (ts *TargetState) Apply(fs vfs.FS, mutator Mutator, applyOptions *ApplyOpti
 	}
 
 	for _, entryName := range sortedEntryNames(ts.Entries) {
-		if err := ts.Entries[entryName].Apply(fs, mutator, applyOptions); err != nil {
+		if err := ts.Entries[entryName].Apply(fs, mutator, follow, applyOptions); err != nil {
 			return err
 		}
 	}


Test patch:
diff --git a/cmd/add_test.go b/cmd/add_test.go
index 2b71a60bd..a1bb127a2 100644
--- a/cmd/add_test.go
+++ b/cmd/add_test.go
@@ -44,11 +44,12 @@ func TestAddAfterModification(t *testing.T) {
 
 func TestAddCommand(t *testing.T) {
 	for _, tc := range []struct {
-		name  string
-		args  []string
-		add   addCmdConfig
-		root  interface{}
-		tests interface{}
+		name   string
+		args   []string
+		add    addCmdConfig
+		follow bool
+		root   interface{}
+		tests  interface{}
 	}{
 		{
 			name: "add_first_file",
@@ -224,13 +225,26 @@ func TestAddCommand(t *testing.T) {
 			},
 		},
 		{
-			name: "add_symlink_follow",
-			args: []string{"/home/user/foo"},
-			add: addCmdConfig{
-				options: chezmoi.AddOptions{
-					Follow: true,
-				},
+			name:   "add_followed_symlink",
+			args:   []string{"/home/user/foo"},
+			follow: true,
+			root: map[string]interface{}{
+				"/home/user":          &vfst.Dir{Perm: 0755},
+				"/home/user/.chezmoi": &vfst.Dir{Perm: 0700},
+				"/home/user/foo":      &vfst.Symlink{Target: "bar"},
+				"/home/user/bar":      "bux",
 			},
+			tests: []vfst.Test{
+				vfst.TestPath("/home/user/.chezmoi/foo",
+					vfst.TestModeIsRegular,
+					vfst.TestContentsString("bux"),
+				),
+			},
+		},
+		{
+			name:   "add_symlink_follow",
+			args:   []string{"/home/user/foo"},
+			follow: true,
 			root: map[string]interface{}{
 				"/home/user":               &vfst.Dir{Perm: 0755},
 				"/home/user/.chezmoi":      &vfst.Dir{Perm: 0700},
@@ -245,13 +259,25 @@ func TestAddCommand(t *testing.T) {
 			},
 		},
 		{
-			name: "add_symlink_follow_double",
+			name: "add_symlink_no_follow",
 			args: []string{"/home/user/foo"},
-			add: addCmdConfig{
-				options: chezmoi.AddOptions{
-					Follow: true,
-				},
+			root: map[string]interface{}{
+				"/home/user":               &vfst.Dir{Perm: 0755},
+				"/home/user/.chezmoi":      &vfst.Dir{Perm: 0700},
+				"/home/user/.dotfiles/foo": "bar",
+				"/home/user/foo":           &vfst.Symlink{Target: ".dotfiles/foo"},
 			},
+			tests: []vfst.Test{
+				vfst.TestPath("/home/user/.chezmoi/symlink_foo",
+					vfst.TestModeIsRegular,
+					vfst.TestContentsString(".dotfiles/foo"),
+				),
+			},
+		},
+		{
+			name:   "add_symlink_follow_double",
+			args:   []string{"/home/user/foo"},
+			follow: true,
 			root: map[string]interface{}{
 				"/home/user":               &vfst.Dir{Perm: 0755},
 				"/home/user/.chezmoi":      &vfst.Dir{Perm: 0700},
@@ -390,6 +416,7 @@ func TestAddCommand(t *testing.T) {
 			c := &Config{
 				SourceDir: "/home/user/.chezmoi",
 				DestDir:   "/home/user",
+				Follow:    tc.follow,
 				Umask:     022,
 				DryRun:    false,
 				Verbose:   true,
diff --git a/cmd/apply_test.go b/cmd/apply_test.go
index 19496113f..d2511f2b8 100644
--- a/cmd/apply_test.go
+++ b/cmd/apply_test.go
@@ -170,6 +170,75 @@ func TestApplyCommand(t *testing.T) {
 	}
 }
 
+func TestApplyFollow(t *testing.T) {
+	for _, tc := range []struct {
+		name   string
+		follow bool
+		root   interface{}
+		tests  []vfst.Test
+	}{
+		{
+			name:   "follow",
+			follow: true,
+			root: map[string]interface{}{
+				"/home/user": map[string]interface{}{
+					"bar": "baz",
+					"foo": &vfst.Symlink{Target: "bar"},
+				},
+				"/home/user/.local/share/chezmoi": map[string]interface{}{
+					"foo": "qux",
+				},
+			},
+			tests: []vfst.Test{
+				vfst.TestPath("/home/user/bar",
+					vfst.TestModeIsRegular,
+					vfst.TestContentsString("qux"),
+				),
+				vfst.TestPath("/home/user/foo",
+					vfst.TestModeType(os.ModeSymlink),
+					vfst.TestSymlinkTarget("bar"),
+				),
+			},
+		},
+		{
+			name:   "nofollow",
+			follow: false,
+			root: map[string]interface{}{
+				"/home/user": map[string]interface{}{
+					"bar": "baz",
+					"foo": &vfst.Symlink{Target: "bar"},
+				},
+				"/home/user/.local/share/chezmoi": map[string]interface{}{
+					"foo": "qux",
+				},
+			},
+			tests: []vfst.Test{
+				vfst.TestPath("/home/user/bar",
+					vfst.TestContentsString("baz"),
+				),
+				vfst.TestPath("/home/user/foo",
+					vfst.TestModeIsRegular,
+					vfst.TestContentsString("qux"),
+				),
+			},
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			fs, cleanup, err := vfst.NewTestFS(tc.root)
+			require.NoError(t, err)
+			defer cleanup()
+			c := &Config{
+				SourceDir: "/home/user/.local/share/chezmoi",
+				DestDir:   "/home/user",
+				Follow:    tc.follow,
+				Umask:     022,
+			}
+			assert.NoError(t, c.runApplyCmd(fs, nil))
+			vfst.RunTests(t, fs, "", tc.tests)
+		})
+	}
+}
+
 func TestApplyRemove(t *testing.T) {
 	for _, tc := range []struct {
 		name     string
diff --git a/lib/chezmoi/targetstate_test.go b/lib/chezmoi/targetstate_test.go
index 6d76d6f3c..c0461a623 100644
--- a/lib/chezmoi/targetstate_test.go
+++ b/lib/chezmoi/targetstate_test.go
@@ -17,6 +17,7 @@ func TestEndToEnd(t *testing.T) {
 		name          string
 		root          interface{}
 		sourceDir     string
+		follow        bool
 		data          map[string]interface{}
 		templateFuncs template.FuncMap
 		destDir       string
@@ -107,7 +108,7 @@ func TestEndToEnd(t *testing.T) {
 				Stdout:            os.Stdout,
 				Umask:             022,
 			}
-			assert.NoError(t, ts.Apply(fs, NewLoggingMutator(os.Stderr, NewFSMutator(fs), false), applyOptions))
+			assert.NoError(t, ts.Apply(fs, NewLoggingMutator(os.Stderr, NewFSMutator(fs), false), tc.follow, applyOptions))
 			vfst.RunTests(t, fs, "", tc.tests)
 		})
 	}