Skip to content

Add relative path fix to git-hub-browse#2087

Open
Cypher1 wants to merge 2 commits into
sorin-ionescu:masterfrom
Cypher1:master
Open

Add relative path fix to git-hub-browse#2087
Cypher1 wants to merge 2 commits into
sorin-ionescu:masterfrom
Cypher1:master

Conversation

@Cypher1
Copy link
Copy Markdown

@Cypher1 Cypher1 commented May 8, 2024

Fixes path handling for the command git-hub-browse to use relative paths.
This enables opening the current working directory or a file in a directory without manually specifying the file path relative to the root.

Proposed Changes

  • Use realpath to get the full path of the file or directory
  • Use git rev-parse --show-toplevel to get the root directory
  • Use sed to remove the root from the full path, making it root relative.
  • Use the pwd (current working directory) as the default path, rather than ""


file="$3"
file="${3:-$(pwd)}"
file="$(command realpath "$file" | sed "s|^$root||")"
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love suggestions on the 'proper' way to do this in zsh as I'm not experienced with it and shellcheck doesn't zsh yet.

Copy link
Copy Markdown

@orzomaxx orzomaxx May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think file="${${file:P}#$root}" will do the work

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the git-hub-browse function to support relative path handling, allowing users to open the current working directory or files without manually specifying paths relative to the repository root.

Changes:

  • Retrieves the git repository root using git rev-parse --show-toplevel
  • Converts file paths to absolute paths using realpath
  • Strips the repository root from file paths to create repository-relative paths
  • Defaults to current working directory when no file path is specified

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


file="$3"
file="${3:-$(pwd)}"
file="$(command realpath "$file" | sed "s|^$root||")"
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The realpath command may not be available on all systems, particularly macOS which doesn't include it by default. Consider using zsh's built-in parameter expansion :A modifier instead, which is the convention used elsewhere in this codebase (e.g., in modules/git/functions/git-dir:10 and modules/python/init.zsh:56). For example: file="${file:A}" would resolve to an absolute path without requiring external commands.

Suggested change
file="$(command realpath "$file" | sed "s|^$root||")"
file="${file:A}"
file="${file#$root}"

Copilot uses AI. Check for mistakes.
Comment on lines +48 to 49
file="$(command realpath "$file" | sed "s|^$root||")"

Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sed pattern s|^$root|| has a potential issue: if $root contains special regex characters (like ., *, [, etc.), they will be interpreted as regex metacharacters rather than literal characters. This could cause incorrect path substitution. The pattern should escape special characters in $root or use a different approach. Additionally, this logic doesn't handle edge cases properly: (1) if the file path doesn't start with $root (file outside repository), the path won't be modified and will result in an incorrect URL; (2) the result will have a leading slash which may not be desired for the GitHub URL.

Suggested change
file="$(command realpath "$file" | sed "s|^$root||")"
file="$(command realpath "$file")"
if [[ "$file" != "$root"* ]]; then
print "$0: path is outside repository: $file" >&2
return 1
fi
file="${file#$root}"
file="${file#/}"

Copilot uses AI. Check for mistakes.
fi

file="$3"
file="${3:-$(pwd)}"
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using $(pwd) as the default when no file is specified is a good improvement, but note that pwd returns an absolute path. This means that when combined with line 48's logic, it should work correctly to extract the repository-relative path. However, consider using the zsh builtin $PWD instead of $(pwd) for better performance and consistency with zsh conventions.

Suggested change
file="${3:-$(pwd)}"
file="${3:-$PWD}"

Copilot uses AI. Check for mistakes.
Comment on lines +48 to 49
file="$(command realpath "$file" | sed "s|^$root||")"

Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more robust and portable approach would be to use zsh's built-in parameter expansion modifiers instead of external commands. For example:

  1. Use file="${file:A}" to get absolute path (instead of realpath)
  2. Use ${file#$root/} to remove the root prefix with a trailing slash (instead of sed)

This handles the leading slash issue correctly and is more portable. Additionally, you should validate that the file is actually within the repository before stripping the prefix, otherwise files outside the repository will produce incorrect URLs.

Suggested change
file="$(command realpath "$file" | sed "s|^$root||")"
file="${file:A}"
if [[ "$file" == "$root" ]]; then
file=""
elif [[ "$file" == "$root"/* ]]; then
file="${file#$root/}"
else
print "$0: file not in repository: $file" >&2
return 1
fi

Copilot uses AI. Check for mistakes.
return 1
fi

root="$(command git rev-parse --show-toplevel)"
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The root variable should be declared as local to follow the convention established in this file (line 17) and in other git functions like git-root (line 10 in modules/git/functions/git-root).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants