-
Notifications
You must be signed in to change notification settings - Fork 0
fix: make ShareCLI validation deterministic #744
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
Changes from 11 commits
5561716
4bb4906
c87e9fe
c1e085b
b05a693
78eb9af
e4e0d26
fcfd7cd
597ff5a
7ec1439
f68136e
348e7c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,29 @@ use std::path::{Path, PathBuf}; | |
| use std::process::Command; | ||
| use std::sync::Mutex; | ||
|
|
||
| /// Git variables that bind a subprocess to the caller's repository. | ||
| /// | ||
| /// Git exports these to hooks. Every command in this module intentionally | ||
| /// operates on an explicit foreign checkout, so inheriting them would let a | ||
| /// hook test inspect or mutate the hook's repository instead. | ||
| const GIT_LOCAL_ENV_VARS: &[&str] = &[ | ||
| "GIT_ALTERNATE_OBJECT_DIRECTORIES", | ||
| "GIT_CONFIG", | ||
| "GIT_CONFIG_PARAMETERS", | ||
| "GIT_CONFIG_COUNT", | ||
| "GIT_OBJECT_DIRECTORY", | ||
| "GIT_DIR", | ||
| "GIT_WORK_TREE", | ||
| "GIT_IMPLICIT_WORK_TREE", | ||
| "GIT_GRAFT_FILE", | ||
| "GIT_INDEX_FILE", | ||
| "GIT_NO_REPLACE_OBJECTS", | ||
| "GIT_REPLACE_REF_BASE", | ||
| "GIT_PREFIX", | ||
| "GIT_SHALLOW_FILE", | ||
| "GIT_COMMON_DIR", | ||
| ]; | ||
|
Comment on lines
+17
to
+36
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. Suggestion: Severity Level: Major
|
||
|
|
||
| /// Error from worktree pool operations. | ||
| #[derive(Debug, thiserror::Error)] | ||
| pub enum WorktreePoolError { | ||
|
|
@@ -150,9 +173,8 @@ impl WorktreePool { | |
| } | ||
|
|
||
| fn ensure_git_repo(path: &Path) -> Result<(), WorktreePoolError> { | ||
| let status = Command::new("git") | ||
| let status = git_command(path) | ||
| .args(["rev-parse", "--git-dir"]) | ||
| .current_dir(path) | ||
| .output() | ||
| .map_err(|e| WorktreePoolError::Git(e.to_string()))?; | ||
| if status.status.success() { | ||
|
|
@@ -163,11 +185,8 @@ fn ensure_git_repo(path: &Path) -> Result<(), WorktreePoolError> { | |
| } | ||
|
|
||
| fn git(cwd: &Path, args: &[&str]) -> Result<String, WorktreePoolError> { | ||
| let out = Command::new("git") | ||
| .args(args) | ||
| .current_dir(cwd) | ||
| .output() | ||
| .map_err(|e| WorktreePoolError::Git(e.to_string()))?; | ||
| let out = | ||
| git_command(cwd).args(args).output().map_err(|e| WorktreePoolError::Git(e.to_string()))?; | ||
| if out.status.success() { | ||
| Ok(String::from_utf8_lossy(&out.stdout).into_owned()) | ||
| } else { | ||
|
|
@@ -181,6 +200,15 @@ fn git(cwd: &Path, args: &[&str]) -> Result<String, WorktreePoolError> { | |
| } | ||
| } | ||
|
|
||
| fn git_command(cwd: &Path) -> Command { | ||
| let mut command = Command::new("git"); | ||
| command.current_dir(cwd); | ||
| for variable in GIT_LOCAL_ENV_VARS { | ||
| command.env_remove(variable); | ||
| } | ||
| command | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
@@ -221,4 +249,15 @@ mod tests { | |
| let err = WorktreePool::open(dir.path(), pool_dir.path()).expect_err("must fail"); | ||
| assert!(matches!(err, WorktreePoolError::NotGitRepo(_))); | ||
| } | ||
|
|
||
| #[test] | ||
| fn git_command_clears_hook_repository_context() { | ||
| let command = git_command(Path::new("/tmp")); | ||
| for variable in GIT_LOCAL_ENV_VARS { | ||
| assert!( | ||
| command.get_envs().any(|(key, value)| key == *variable && value.is_none()), | ||
| "{variable} must not leak into a foreign git command" | ||
| ); | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.