Skip to content

Don't resolve symlinks with cd - #5190

Merged
ridiculousfish merged 3 commits into
fish-shell:masterfrom
ridiculousfish:virtualpwd
Oct 7, 2018
Merged

Don't resolve symlinks with cd#5190
ridiculousfish merged 3 commits into
fish-shell:masterfrom
ridiculousfish:virtualpwd

Conversation

@ridiculousfish

@ridiculousfish ridiculousfish commented Sep 17, 2018

Copy link
Copy Markdown
Member

This teaches fish to maintain a virtual PWD, similar to other shells. It no longer resolves symlinks. #3350 for more.

pwd -P can be used to access the physical (resolved) working directory. This is part of the shell spec.

(This ended up being pretty straightforward.)

This PR is an opportunity for discussion / pushback.

@faho

faho commented Sep 17, 2018

Copy link
Copy Markdown
Member

The hg prompt will need adjustment after this. Because hg is sooooo slow, we check if something can possibly be a hg repo by seeing if there is a ".hg" directory in any parent directory:

    # Find an hg directory above $PWD
    # without calling `hg root` because that's too slow
    set -l root
    set -l dir $PWD
    while test $dir != "/"
        if test -f $dir'/.hg/dirstate'
            set root $dir"/.hg"
            break
        end
        # Go up one directory
        set dir (string replace -r '[^/]*/?$' '' $dir)
    end

If $PWD is "virtual", then that means we'd follow symlinks back. hg won't, so we'd have to use the "physical" pwd here.

I would assume basically any work done on $PWD will want to switch to the physical one, which makes me think: Why don't we still keep that as physical, and just offer a separate $LOGICAL_PWD (and pwd -L, cd -L)?

@zanchey

zanchey commented Sep 17, 2018

Copy link
Copy Markdown
Member

I think //./someshare is valid on Windows, although perhaps @mqudsi can clarify whether that's something you can actually navigate to.

I'm not strongly attached to the existing behaviour, but I think it's worth noting somewhere in the cd documentation the problems this causes as you outlined in #1957 (comment).

@mqudsi

mqudsi commented Sep 18, 2018

Copy link
Copy Markdown
Contributor

@zanchey not exactly.

\\servername\share is an smb/cifs path under Windows, but . is not a valid server name (and it isn't an alias for localhost or anything). \\.\ is a kernel-level construct known as a dos device path. To backtrack, a path like C:\foo is dos-style path only valid in user mode. Kernel mode paths start with \\ followed by a namespace. . is the namespace for dos-style paths, so C:\foo becomes \\.\C:\foo when mapped into kernel namespace. Other namespaces include ?, ??, smb server paths, and more.

The paths are symbolically linked to the NT namespace path in the registry, but that's not a file-level symbolic link but rather a device/volume-level symbolic link that is a layer or two of abstraction apart from the filesystem.

Much more info here: https://blogs.msdn.microsoft.com/jeremykuhne/2016/05/02/dos-to-nt-a-paths-journey/

@luispabon

luispabon commented Sep 27, 2018

Copy link
Copy Markdown

I would like this change, if not the default at least should be configurable although looking at the PR I can see it'd be somewhat messy to implement like so.

A lot of shell apps are built around standard sh and later on bash behaviours.

One use case where fish's default behaviour breaks user flow.

When working in Golang, it expects all your projects and their dependencies to live in $GOPATH (by default this is ~/go/src), and we normally organise different workspaces by symlinking from somewhere into $GOPATH. This is all well and good until you try to cd into one such directory to compile a go app, which makes running go a hassle under fish. It just won't work unless we run the go binary through a different shell, or change the direction of symlinks (from $GOPATH to my workspace).

This new function performs normalization of paths including dropping
/./ segments, and resolving /../ segments, in preparation for switching
fish to a "virtual" PWD.
This switches fish to a "virtual" PWD, where it no longer uses getcwd to
discover its PWD but instead synthesizes it based on normalizing cd against
the $PWD variable.

Both pwd and $PWD contain the virtual path. pwd is taught about -P to
return the physical path, and -L the logical path (which is the default).

Fixes fish-shell#3350
The hg prompt walks up the directory hierarchy to decide if we are in a
repo subdirectory. Because hg is an external command, it resolves symlinks.
Switch to using pwd -P so hg and fish will have the same view of the hg repo.

Based on comment:
fish-shell#5190 (comment)
@ridiculousfish
ridiculousfish merged commit 3e4bdf5 into fish-shell:master Oct 7, 2018
@ridiculousfish

Copy link
Copy Markdown
Member Author

Merged as 786c0c5

ridiculousfish added a commit to ridiculousfish/fish-shell that referenced this pull request Oct 7, 2018
The hg prompt walks up the directory hierarchy to decide if we are in a
repo subdirectory. Because hg is an external command, it resolves symlinks.
Switch to using pwd -P so hg and fish will have the same view of the hg repo.

Based on comment:
fish-shell#5190 (comment)
@zanchey zanchey added this to the fish-3.0 milestone Oct 7, 2018
ridiculousfish added a commit to ridiculousfish/fish-shell that referenced this pull request Nov 24, 2018
The hg prompt walks up the directory hierarchy to decide if we are in a
repo subdirectory. Because hg is an external command, it resolves symlinks.
Switch to using pwd -P so hg and fish will have the same view of the hg repo.

Based on comment:
fish-shell#5190 (comment)
ridiculousfish added a commit to ridiculousfish/fish-shell that referenced this pull request Nov 24, 2018
The hg prompt walks up the directory hierarchy to decide if we are in a
repo subdirectory. Because hg is an external command, it resolves symlinks.
Switch to using pwd -P so hg and fish will have the same view of the hg repo.

Based on comment:
fish-shell#5190 (comment)
ridiculousfish added a commit to ridiculousfish/fish-shell that referenced this pull request Dec 2, 2018
The hg prompt walks up the directory hierarchy to decide if we are in a
repo subdirectory. Because hg is an external command, it resolves symlinks.
Switch to using pwd -P so hg and fish will have the same view of the hg repo.

Based on comment:
fish-shell#5190 (comment)
@justinlindh

Copy link
Copy Markdown

I'd noticed this change after upgrading my fish shell today. Since symlinks are no longer being resolved, the "jump" plugin shows the path of the symlink. The argument whether this is desired behavior or not isn't one I want to get into (nor am I qualified to), but for anybody else who just wants their jump plugin to resolve the symlinked path, a quick fix is to add the following line to jump.fish (mine is at ~/.local/share/omf/pkg/jump/functions/jump.fish, using omf).

cd $MARKPATH/$argv[1]
cd (pwd -P)

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Apr 17, 2020
@ridiculousfish
ridiculousfish deleted the virtualpwd branch August 22, 2020 18:54
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants