-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(shell-out): allow shelling out to git for network related calls
Reasoning: `jj` fails to push/fetch over ssh depending on the system. Issue jj-vcs#4979 lists over 20 related issues on this and proposes shelling out to `git` for tasks related to the network (in fact, just push/fetch are enough). This PR implements this. Implementation Details: This PR implements shelling out to `git` via `std::process::Command`. There are 2 sharp edges with the patch: - it relies on having to parse out git errors to match the error codes (and parsing git2's errors in one particular instance to match the error behaviour). This seems mostly unavoidable - it is using a new feature flag `shell` to switch on to shelling out. this doesn't seem the best approach, and it would be great to get some feedback on what would be best. A flag on jj git + adding it to the jj config seems to be a good enough idea Testing: Run the rust tests: ``` $ cargo test # checks we didn't screw up the baseline $ cargo test --features=shell # test the shelling out ``` Build with shell-out enabled: ``` $ cargo build --features=shell ``` Clone a private repo: ``` $ jj git clone <REPO_SSH_URL> ``` Create new commit and push ``` $ echo "TEST" > this_is_a_test_file.txt $ jj describe -m 'test commit' $ jj git push -b <branch> ```
- Loading branch information
Showing
6 changed files
with
939 additions
and
85 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 |
---|---|---|
|
@@ -96,10 +96,10 @@ fn test_git_clone() { | |
let stdout = test_env.normalize_output(&get_stdout_string(&assert)); | ||
let stderr = test_env.normalize_output(&get_stderr_string(&assert)); | ||
insta::assert_snapshot!(stdout, @""); | ||
insta::assert_snapshot!(stderr, @r###" | ||
insta::assert_snapshot!(stderr, @r#" | ||
Fetching into new repo in "$TEST_ENV/failed" | ||
Error: could not find repository at '$TEST_ENV/bad'; class=Repository (6) | ||
"###); | ||
Error: could not find repository at '$TEST_ENV/bad' | ||
"#); | ||
assert!(!test_env.env_root().join("failed").exists()); | ||
|
||
// Failed clone shouldn't remove the existing destination directory | ||
|
@@ -111,10 +111,10 @@ fn test_git_clone() { | |
let stdout = test_env.normalize_output(&get_stdout_string(&assert)); | ||
let stderr = test_env.normalize_output(&get_stderr_string(&assert)); | ||
insta::assert_snapshot!(stdout, @""); | ||
insta::assert_snapshot!(stderr, @r###" | ||
insta::assert_snapshot!(stderr, @r#" | ||
Fetching into new repo in "$TEST_ENV/failed" | ||
Error: could not find repository at '$TEST_ENV/bad'; class=Repository (6) | ||
"###); | ||
Error: could not find repository at '$TEST_ENV/bad' | ||
"#); | ||
assert!(test_env.env_root().join("failed").exists()); | ||
assert!(!test_env.env_root().join("failed").join(".jj").exists()); | ||
|
||
|
@@ -284,10 +284,10 @@ fn test_git_clone_colocate() { | |
let stdout = test_env.normalize_output(&get_stdout_string(&assert)); | ||
let stderr = test_env.normalize_output(&get_stderr_string(&assert)); | ||
insta::assert_snapshot!(stdout, @""); | ||
insta::assert_snapshot!(stderr, @r###" | ||
insta::assert_snapshot!(stderr, @r#" | ||
Fetching into new repo in "$TEST_ENV/failed" | ||
Error: could not find repository at '$TEST_ENV/bad'; class=Repository (6) | ||
"###); | ||
Error: could not find repository at '$TEST_ENV/bad' | ||
"#); | ||
assert!(!test_env.env_root().join("failed").exists()); | ||
|
||
// Failed clone shouldn't remove the existing destination directory | ||
|
@@ -302,10 +302,10 @@ fn test_git_clone_colocate() { | |
let stdout = test_env.normalize_output(&get_stdout_string(&assert)); | ||
let stderr = test_env.normalize_output(&get_stderr_string(&assert)); | ||
insta::assert_snapshot!(stdout, @""); | ||
insta::assert_snapshot!(stderr, @r###" | ||
insta::assert_snapshot!(stderr, @r#" | ||
Fetching into new repo in "$TEST_ENV/failed" | ||
Error: could not find repository at '$TEST_ENV/bad'; class=Repository (6) | ||
"###); | ||
Error: could not find repository at '$TEST_ENV/bad' | ||
"#); | ||
assert!(test_env.env_root().join("failed").exists()); | ||
assert!(!test_env.env_root().join("failed").join(".git").exists()); | ||
assert!(!test_env.env_root().join("failed").join(".jj").exists()); | ||
|
@@ -586,6 +586,7 @@ fn test_git_clone_trunk_deleted() { | |
"#); | ||
} | ||
|
||
#[cfg(not(feature = "shell"))] | ||
#[test] | ||
fn test_git_clone_with_depth() { | ||
let test_env = TestEnvironment::default(); | ||
|
@@ -606,6 +607,43 @@ fn test_git_clone_with_depth() { | |
"#); | ||
} | ||
|
||
#[cfg(feature = "shell")] | ||
#[test] | ||
fn test_git_clone_with_depth() { | ||
let test_env = TestEnvironment::default(); | ||
test_env.add_config("git.auto-local-bookmark = true"); | ||
let git_repo_path = test_env.env_root().join("source"); | ||
let clone_path = test_env.env_root().join("clone"); | ||
let git_repo = git2::Repository::init(git_repo_path).unwrap(); | ||
set_up_non_empty_git_repo(&git_repo); | ||
|
||
// local transport *does* work in normal git | ||
// we check everything works | ||
let (stdout, stderr) = test_env.jj_cmd_ok( | ||
test_env.env_root(), | ||
&["git", "clone", "--depth", "1", "source", "clone"], | ||
); | ||
insta::assert_snapshot!(stdout, @""); | ||
insta::assert_snapshot!(stderr, @r#" | ||
Fetching into new repo in "$TEST_ENV/clone" | ||
bookmark: main@origin [new] tracked | ||
Setting the revset alias "trunk()" to "main@origin" | ||
Working copy now at: sqpuoqvx cad212e1 (empty) (no description set) | ||
Parent commit : mzyxwzks 9f01a0e0 main | message | ||
Added 1 files, modified 0 files, removed 0 files | ||
"#); | ||
|
||
let (stdout, stderr) = test_env.jj_cmd_ok(&clone_path, &["log"]); | ||
insta::assert_snapshot!(stdout, @r" | ||
@ sqpuoqvx [email protected] 2001-02-03 08:05:07 cad212e1 | ||
│ (empty) (no description set) | ||
◆ mzyxwzks [email protected] 1970-01-01 11:00:00 main 9f01a0e0 | ||
│ message | ||
~ | ||
"); | ||
insta::assert_snapshot!(stderr, @""); | ||
} | ||
|
||
#[test] | ||
fn test_git_clone_invalid_immutable_heads() { | ||
let test_env = TestEnvironment::default(); | ||
|
This file contains 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
Oops, something went wrong.