Skip to content

Commit

Permalink
Add --follow option to add command
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Jun 9, 2019
1 parent 4586dfb commit 008513f
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 1 deletion.
1 change: 1 addition & 0 deletions cmd/add.go
Expand Up @@ -35,6 +35,7 @@ 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")
Expand Down
43 changes: 43 additions & 0 deletions cmd/add_test.go
Expand Up @@ -200,6 +200,49 @@ func TestAddCommand(t *testing.T) {
),
},
},
{
name: "add_symlink_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/foo",
vfst.TestModeIsRegular,
vfst.TestContentsString("bar"),
),
},
},
{
name: "add_symlink_follow_double",
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/baz": "qux",
"/home/user/foo": &vfst.Symlink{Target: "bar"},
"/home/user/bar": &vfst.Symlink{Target: ".dotfiles/baz"},
},
tests: []vfst.Test{
vfst.TestPath("/home/user/.chezmoi/foo",
vfst.TestModeIsRegular,
vfst.TestContentsString("qux"),
),
},
},
{
name: "add_symlink_in_dir_recursive",
args: []string{"/home/user/foo"},
Expand Down
6 changes: 6 additions & 0 deletions cmd/helps.gen.go
Expand Up @@ -22,6 +22,12 @@ 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" +
Expand Down
16 changes: 16 additions & 0 deletions docs/HOWTO.md
Expand Up @@ -21,6 +21,7 @@
* [Export archives](#export-archives)
* [Use a non-git version control system](#use-a-non-git-version-control-system)
* [Use a merge tool other than vimdiff](#use-a-merge-tool-other-than-vimdiff)
* [Migrate from a dotfile manager that uses symlinks](#migrate-from-a-dotfile-manager-that-uses-symlinks)

## Use a hosted repo to manage your dotfiles across multiple machines

Expand Down Expand Up @@ -523,3 +524,18 @@ neovim's diff mode specify:
[merge]
command = "nvim"
args = "-d"


## Migrate from a dotfile manager that uses symlinks

Many dotfile managers replace dotfiles with symbolic links to files in a common
directory. If you `chezmoi add` such a symlink, chezmoi will add the symlink,
not the file. To assist with migrating from symlink-based systems, use the
`--follow` / `-f` option to `chezmoi add`, for example:

chezmoi add --follow ~/.bashrc

This will tell `chezmoi add` that the target state of `~/.bashrc` is the target
of the `~/.bashrc` symlink, rather than the symlink itself. When you run
`chezmoi apply`, chezmoi will replace the `~/.bashrc` symlink with the file
contents.
6 changes: 6 additions & 0 deletions docs/REFERENCE.md
Expand Up @@ -290,6 +290,12 @@ 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.
Expand Down
12 changes: 11 additions & 1 deletion lib/chezmoi/targetstate.go
Expand Up @@ -30,6 +30,7 @@ type AddOptions struct {
Empty bool
Encrypt bool
Exact bool
Follow bool
Template bool
}

Expand Down Expand Up @@ -83,7 +84,16 @@ func (ts *TargetState) Add(fs vfs.FS, addOptions AddOptions, targetPath string,
}
if info == nil {
var err error
info, err = fs.Lstat(targetPath)
if addOptions.Follow {
info, err = fs.Stat(targetPath)
} else {
info, err = fs.Lstat(targetPath)
}
if err != nil {
return err
}
} else if addOptions.Follow && info.Mode()&os.ModeType == os.ModeSymlink {
info, err = fs.Stat(targetPath)
if err != nil {
return err
}
Expand Down

0 comments on commit 008513f

Please sign in to comment.