Add relative path fix to git-hub-browse#2087
Conversation
|
|
||
| file="$3" | ||
| file="${3:-$(pwd)}" | ||
| file="$(command realpath "$file" | sed "s|^$root||")" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I think file="${${file:P}#$root}" will do the work
There was a problem hiding this comment.
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||")" |
There was a problem hiding this comment.
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.
| file="$(command realpath "$file" | sed "s|^$root||")" | |
| file="${file:A}" | |
| file="${file#$root}" |
| file="$(command realpath "$file" | sed "s|^$root||")" | ||
|
|
There was a problem hiding this comment.
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.
| 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#/}" |
| fi | ||
|
|
||
| file="$3" | ||
| file="${3:-$(pwd)}" |
There was a problem hiding this comment.
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.
| file="${3:-$(pwd)}" | |
| file="${3:-$PWD}" |
| file="$(command realpath "$file" | sed "s|^$root||")" | ||
|
|
There was a problem hiding this comment.
A more robust and portable approach would be to use zsh's built-in parameter expansion modifiers instead of external commands. For example:
- Use
file="${file:A}"to get absolute path (instead of realpath) - 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.
| 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 |
| return 1 | ||
| fi | ||
|
|
||
| root="$(command git rev-parse --show-toplevel)" |
There was a problem hiding this comment.
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).
Fixes path handling for the command
git-hub-browseto 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
realpathto get the full path of the file or directorygit rev-parse --show-toplevelto get the root directorysedto remove the root from the full path, making it root relative.pwd(current working directory) as the default path, rather than ""