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

**URL:** <https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932>\
**Category:** General Usage\
**Tags:** wat\
**Created:** [December 21, 2023, 10:48pm UTC](https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932 "2023-12-21T22:48:18Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [December 21, 2023, 10:48pm UTC](https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932/1 "2023-12-21T22:48:18Z")

</div>

```julia
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?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 21, 2023, 11:01pm UTC](https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932/2 "2023-12-21T23:01:27Z")

</div>

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

```python
In [1]: import os

In [2]: os.path.relpath("tatooine", "naboo")
Out[2]: '../tatooine'

```

```ruby
irb(main):001:0> require 'pathname'
=> true
irb(main):002:0> Pathname.new("tatooine").relative_path_from("naboo")
=> #<Pathname:../tatooine>

```

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [December 22, 2023, 12:52pm UTC](https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932/3 "2023-12-22T12:52:28Z")

</div>

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 `abspath`ed before computing `relpath`:

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

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

```

---

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [December 22, 2023, 1:37pm UTC](https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932/4 "2023-12-22T13:37:09Z")

</div>

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

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

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [December 22, 2023, 2:15pm UTC](https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932/5 "2023-12-22T14:15:36Z")

</div>

What doesn’t make sense with absolute paths?

```julia
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`

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [December 22, 2023, 2:26pm UTC](https://discourse.julialang.org/t/why-is-relpath-x-y-x/107932/6 "2023-12-22T14:26:21Z")

</div>

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

```julia
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
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]](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13), though.

Edit: reference for the POSIX manual added.
