andsens / homeshick

git dotfiles synchronizer written in bash

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[FR] revert c39ef17 - Symlinks are now relative.

laur89 opened this issue · comments

Just updated homeshick after a year or so and discovered half of my links are broken, c39ef17 being the most likely culprit. This stems from my extensive corner-case usage, where files in castle/home are themselves links pointing to a directory in the root of castle. Consider this castle example:

.
├── home
│   └── dev -> ../../scripts/
├── scripts

Before the commit, target ~/dev/scripts would point correctly at
~/dev/scripts -> /home/laur89/.homesick/repos/example/home/dev/scripts

whereas now it's ~/dev/scripts -> ../.homesick/repos/example/home/dev/scripts

It would all be nice, but ~/dev itself is pointed at dev -> .homesick/repos/another_castle/home/dev (managed by another castle), rendering scripts -> ../.homeshick/... incorrect.

Edit: looks like the first characteristic (using links pointing to dir in a castle root) is not really important. What matters is the fact ~/dev has different realpath.

OK, that surprises me a little. I have added a boatload of tests before I even considered pushing this, stability is a top priority for me with this project.

I am having a little trouble understanding the structure you laid out.

Before the commit, target ~/dev/scripts would point correctly at
~/dev/scripts -> /home/laur89/.homesick/repos/example/home/dev/scripts

whereas now it's ~/dev/scripts -> ../.homesick/repos/example/home/dev/scripts

Why would ~/dev/scripts point at antyhing? home/dev is a symlink in the example castle, correct? So ~/dev should be a symlink to .homesick/repos/example/home/dev. What happens beyond that shouldn't have anything to do with homeshick.

It would all be nice, but ~/dev itself is pointed at dev -> .homesick/repos/another_castle/home/dev (managed by another castle), rendering scripts -> ../.homeshick/... incorrect.

Am I understanding it correctly that you have the same home/ path defined twice in two different castles? That would indeed lead to unexpected results.

I think you need to either create one or two more of your dir tree diagrams or simply post a script that can be run with test/interactive that reproduces the problem.

p.s.: I actually use the same system, where most of the files in home/ are symlinks to somewhere else in the same repo.

Damn, messed example tree up. It should've been

├── home
│   └── dev
│       └── scripts -> ../../scripts/
├── scripts

another_castle tree:

.
├── home
│   ├── dev -> /data/actual_target_dir/

Am I understanding it correctly that you have the same home/ path defined twice in two different castles?

Correct. Castle example (the first tree above) manages scripts under home/dev, and another_castle manages home/dev itself, pointing it at a real directory outside of castles.

$ ls ~/.homesick/repos/another_castle/home
dev -> /data/actual_target_dir

$ ls ~/.homesick/repos/example/home/dev
scripts -> ../../scripts/

And now when we look at the linking result:

$ ls ~
dev -> .homesick/repos/another_castle/home/dev

$ ls ~/dev   (note realpath is here /data/actual_target_dir)
scripts -> ../.homesick/repos/example/home/dev/scripts

Shell is unable to resolve scripts to its target here, although manually cd-ing to the relative target works. But in any case, this is all wrong:

$ ls /data/actual_target_dir
scripts -> ../.homesick/repos/example/home/dev/scripts

Full paths seem like a way more robust solution.

Ah OK. I see the problem now. I will not revert the commit for relative symlinks, it fixes a slew of other problems like symlinking in chrooted environments, renaming user folders etc.

However, this is actually a bug! homeshick should recognize that the parent folder is a symlink and adjust the relative path accordingly. I will try and get this fixed, though it might take a while since the required code is not trivial.

p.s.: The way your repos are structure, you rely on the order in which homeshick symlinks. i.e. create the directory symlink first, then link the scripts file. If this were to happen the other way around your setup would not work. I cannot guarantee that this ordering will be preserved throughout all future versions.

The way your repos are structure, you rely on the order in which homeshick symlinks. i.e. create the directory symlink first, then link the scripts file.

Yeh I'm aware of this. The way I'm using homeshick, is splitting dotfiles into multiple tiers - common dotfiles, computer-specific dots, private dotfiles etc; setup script then handles these castles in required order. Not ideal, but it works for me.

Alright! I believe I have fixed the problem while still using relative symlinks. Would you care to try again? Make sure to checkout the testing branch.

These tests should ensure that there is no regression of the reported issue.

Fixed in master now.