Why is relpath("x","y") == "../x"?

julia> relpath("tatooine", "naboo")
"../tatooine"

The docs say
relpath(path::AbstractString, startpath::AbstractString = ".") -> AbstractString

Return a relative filepath to path either from the current directory or from an optional start directory. This is a path computation: the filesystem is not accessed to confirm the existence or nature of path or startpath.

But it seems like as a purely path operation, the answer should be “you can’t get there from here”? relpath("tatooine", "naboo") == "../tatooine" seems to imply that tatooine and naboo are adjacent directories, but…that might not be true?

I don’t know, but other tools behave similarly:

In [1]: import os

In [2]: os.path.relpath("tatooine", "naboo")
Out[2]: '../tatooine'
irb(main):001:0> require 'pathname'
=> true
irb(main):002:0> Pathname.new("tatooine").relative_path_from("naboo")
=> #<Pathname:../tatooine>
1 Like

One way to make sense of this is to consider both paths as paths below your current directory, e.g. relpath("/tmp/tatooine", "/tmp/naboo") and then I think "../tatooine" is a reasonable result. That is in fact also what happens; you can mix relative and absolute paths in your call and they will both be abspathed before computing relpath:

julia> pwd()
"/home/gunnar/advent_of_code"

julia> relpath("2023/input/", "/home/gunnar/advent_of_code/2023")
"input"

That makes sense when there are relative paths in the inputs, but this happens even with absolute paths!

julia> relpath("/a","/b")
"../a"

What doesn’t make sense with absolute paths?

shell$ julia -e 'relpath("/tmp", "/home") |> println'
../tmp

shell$ cd /home; pwd
/home

shell$ cd ../tmp; pwd
/tmp

I find nothing surprising here: ../tmp is a relative path allowing to refer to /tmp when the working directory is /home

1 Like

I had to look this up but it seems totally consistent with the docstring.

help?> relpath
search: relpath realpath

  relpath(path::AbstractString, startpath::AbstractString = ".") -> AbstractString

  Return a relative filepath to path either from the current directory or from an optional start directory. This is a
  path computation: the filesystem is not accessed to confirm the existence or nature of path or startpath.

So in the case of

julia> relpath("tatooine", "naboo")
"../tatooine"

you’re asking Julia: if I were in a directory ./naboo and wanted the relative address of directory ./tatooine, then the answer would be ../tatooine, i.e. go up one from within naboo and you’ll find it there. That’s the standard POSIX interpretation of relative paths[1], though.

Edit: reference for the POSIX manual added.

2 Likes