-
-
Notifications
You must be signed in to change notification settings - Fork 71
feat(git): support GIT_DIR/GIT_WORK_TREE for bare-repo dotfile managers #847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,12 +5,39 @@ use eyre::eyre; | |||||
| use crate::Result; | ||||||
|
|
||||||
| /// Find the `.git` path from the current working directory by searching upward. | ||||||
| /// | ||||||
| /// Honors `GIT_DIR` if set (used by bare-repo dotfile managers like YADM), in | ||||||
| /// which case the returned path may be a bare repository directory rather than | ||||||
| /// a `.git` file/dir. | ||||||
| pub fn find_git_path() -> Result<PathBuf> { | ||||||
| if let Some(git_dir) = std::env::var_os("GIT_DIR") { | ||||||
| let p = PathBuf::from(&git_dir); | ||||||
| let p = if p.is_absolute() { | ||||||
| p | ||||||
| } else { | ||||||
| std::env::current_dir()?.join(p) | ||||||
| }; | ||||||
| return Ok(p); | ||||||
| } | ||||||
| let cwd = std::env::current_dir()?; | ||||||
| xx::file::find_up(&cwd, &[".git"]) | ||||||
| .ok_or_else(|| eyre!("No .git found in this or any parent directory")) | ||||||
| } | ||||||
|
|
||||||
| /// Return the effective working-tree root, honoring `GIT_WORK_TREE` when set | ||||||
| /// (for bare-repo setups like YADM). Falls back to walking up for `.git`, and | ||||||
| /// finally to `cwd` if no repository is found. | ||||||
| pub fn find_work_tree_root() -> PathBuf { | ||||||
| let cwd = std::env::current_dir().unwrap_or_default(); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
Suggested change
|
||||||
| if let Some(wt) = std::env::var_os("GIT_WORK_TREE") { | ||||||
| let p = PathBuf::from(&wt); | ||||||
| return if p.is_absolute() { p } else { cwd.join(p) }; | ||||||
| } | ||||||
| xx::file::find_up(&cwd, &[".git"]) | ||||||
| .and_then(|p| p.parent().map(|p| p.to_path_buf())) | ||||||
| .unwrap_or(cwd) | ||||||
| } | ||||||
|
|
||||||
| /// Given a `.git` path (found by find_up), resolve the actual git directory. | ||||||
| /// - If `.git` is a directory → return it as-is | ||||||
| /// - If `.git` is a file (worktree) → read it, parse "gitdir: <path>", resolve that path | ||||||
|
|
||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| #!/usr/bin/env bats | ||
|
|
||
| # Regression tests for #831 — support bare-repo dotfile managers (YADM, etc.) | ||
| # that set GIT_DIR and GIT_WORK_TREE instead of using a `.git` in the worktree. | ||
|
|
||
| setup() { | ||
| load 'test_helper/common_setup' | ||
| _common_setup | ||
|
|
||
| BARE_DIR="$TEST_TEMP_DIR/bare.git" | ||
| WORK_TREE="$TEST_TEMP_DIR/home" | ||
| git init --bare "$BARE_DIR" | ||
| mkdir -p "$WORK_TREE" | ||
|
|
||
| export GIT_DIR="$BARE_DIR" | ||
| export GIT_WORK_TREE="$WORK_TREE" | ||
| cd "$WORK_TREE" | ||
|
|
||
| echo "initial" > file.txt | ||
| git add file.txt | ||
| git commit -m "initial commit" | ||
| } | ||
|
|
||
| teardown() { | ||
| unset GIT_DIR | ||
| unset GIT_WORK_TREE | ||
| _common_teardown | ||
| } | ||
|
|
||
| _write_hk_config() { | ||
| cat <<EOF > hk.pkl | ||
| amends "$PKL_PATH/Config.pkl" | ||
| hooks { | ||
| ["check"] { steps { ["echo"] { check = "echo checked {{files}}" } } } | ||
| ["pre-commit"] { steps { ["echo"] { check = "echo pre-commit {{files}}" } } } | ||
| } | ||
| EOF | ||
| } | ||
|
|
||
| @test "hk builtins works with no repo config" { | ||
| # Outside any repo, with no hk.pkl, should not panic | ||
| cd "$TEST_TEMP_DIR" | ||
| unset GIT_DIR | ||
| unset GIT_WORK_TREE | ||
| run hk builtins | ||
| assert_success | ||
| assert_output --partial "prettier" | ||
| } | ||
|
|
||
| @test "hk check honors GIT_DIR/GIT_WORK_TREE" { | ||
| _write_hk_config | ||
| git add hk.pkl | ||
| git commit -m "add hk config" | ||
|
|
||
| run hk check --all | ||
| assert_success | ||
| assert_output --partial "checked" | ||
| } | ||
|
|
||
| @test "hk check with HK_LIBGIT2=0 honors GIT_DIR/GIT_WORK_TREE" { | ||
| _write_hk_config | ||
| git add hk.pkl | ||
| git commit -m "add hk config" | ||
|
|
||
| HK_LIBGIT2=0 run hk check --all | ||
| assert_success | ||
| assert_output --partial "checked" | ||
| } | ||
|
|
||
| @test "hk install writes hooks to the bare-repo hooks dir" { | ||
| _write_hk_config | ||
|
|
||
| run hk install | ||
| assert_success | ||
| assert_file_exists "$BARE_DIR/hooks/pre-commit" | ||
| } | ||
|
|
||
| @test "hk uninstall removes hooks from the bare-repo hooks dir" { | ||
| _write_hk_config | ||
|
|
||
| hk install | ||
| assert_file_exists "$BARE_DIR/hooks/pre-commit" | ||
|
|
||
| run hk uninstall | ||
| assert_success | ||
| assert_file_not_exists "$BARE_DIR/hooks/pre-commit" | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By skipping
set_current_dirwhenGIT_DIRorGIT_WORK_TREEis set,hkremains in the user's current working directory. This breaks many internal operations (likestatusorall_files) that expect the process to be at the repository root to correctly resolve relative paths returned by Git.Additionally, if we do change the directory, any relative paths in
GIT_DIRorGIT_WORK_TREEmust be converted to absolute paths first, otherwise they will point to the wrong location after thecd.