Skip to content

Commit 28464b5

Browse files
ByronCopilot
andcommitted
Turn https://github.com/staehle/gitoxide-testing` into a local script to avoid the network.
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent bb48bae commit 28464b5

4 files changed

Lines changed: 174 additions & 9 deletions

File tree

Binary file not shown.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/bin/bash
2+
# Reproduces the history and content of https://github.com/staehle/gitoxide-testing
3+
# for use in journey tests without requiring network access.
4+
#
5+
# Note: This script is designed to be run via `jtt run-script` which sets up
6+
# a controlled Git environment with fixed author/committer dates. The resulting
7+
# commit hashes will differ from the original repository but the content and
8+
# structure will be semantically equivalent.
9+
set -eu -o pipefail
10+
11+
git init -q
12+
13+
# Configure the repository to allow partial clone filters when served via file://
14+
git config uploadpack.allowFilter true
15+
git config uploadpack.allowAnySHA1InWant true
16+
17+
# Initial commit (simulating GitHub's initial commit)
18+
cat > LICENSE << 'EOF'
19+
MIT License
20+
21+
Copyright (c) 2026 Jake Staehle
22+
23+
Permission is hereby granted, free of charge, to any person obtaining a copy
24+
of this software and associated documentation files (the "Software"), to deal
25+
in the Software without restriction, including without limitation the rights
26+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27+
copies of the Software, and to permit persons to whom the Software is
28+
furnished to do so, subject to the following conditions:
29+
30+
The above copyright notice and this permission notice shall be included in all
31+
copies or substantial portions of the Software.
32+
33+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
SOFTWARE.
40+
EOF
41+
42+
cat > README.md << 'EOF'
43+
# gitoxide-testing
44+
example repo to use in gitoxide functional tests
45+
EOF
46+
47+
git add LICENSE README.md
48+
git commit -q -m "Initial commit"
49+
50+
# Version 1 commit
51+
cat > README.md << 'EOF'
52+
# gitoxide-testing
53+
Example repo to use in gitoxide functional tests
54+
55+
For use with journey tests in: https://github.com/GitoxideLabs/gitoxide
56+
57+
EOF
58+
59+
echo "This is version 1.0" > version.txt
60+
git add README.md version.txt
61+
git commit -q -m "version 1 commit"
62+
git tag v1
63+
64+
# Version 2 commit
65+
echo "This is version 2.0" > version.txt
66+
touch new-file-in-v2
67+
git add version.txt new-file-in-v2
68+
git commit -q -m "version 2"
69+
git tag v2
70+
71+
# Commit between versions - removes new-file-in-v2, adds another-new-file, updates version
72+
echo "This is version 2.1" > version.txt
73+
echo "This should exist starting in version 2" > another-new-file
74+
git rm -q new-file-in-v2
75+
git add version.txt another-new-file
76+
git commit -q -m "a commit between versions"
77+
78+
# Adds a script (non-executable)
79+
cat > a_script.sh << 'EOF'
80+
#!/bin/sh
81+
82+
echo "This is a script!"
83+
echo "It does things!"
84+
85+
exit 0
86+
EOF
87+
git add a_script.sh
88+
git commit -q -m "adds a script (non-executable)"
89+
90+
# Version 3 commit
91+
echo "This is version 3.0" > version.txt
92+
git add version.txt
93+
git commit -q -m "version 3"
94+
git tag v3
95+
96+
# Make script executable
97+
chmod +x a_script.sh
98+
git add a_script.sh
99+
git commit -q -m "just changes the file mode for a_script.sh from 644 to 755"
100+
101+
# Version 4 commit
102+
echo "This is version 4.0" > version.txt
103+
104+
cat > CHANGELOG.md << 'EOF'
105+
# Summary of commits in this repo and what to test for:
106+
107+
1. `v1`: Just adds `version.txt` and updates the README
108+
2. `v2`: Immediately after v1, adds `new-file-in-v2`, and updates `version.txt` (all tags should have bumped versions of this)
109+
3. `v3`: Has three commits after v2, adds `another-new-file` and a non-executable script `a_script.sh`
110+
4. `v4`: Fixes the script to be executable
111+
EOF
112+
113+
git add version.txt CHANGELOG.md
114+
git commit -q -m "version 4"
115+
git tag v4
116+
117+
# Version 5 commit
118+
cat > README.md << 'EOF'
119+
# gitoxide-testing
120+
Example repo to use in gitoxide functional tests
121+
122+
For use with journey tests in: https://github.com/GitoxideLabs/gitoxide
123+
124+
# Summary of commits in this repo and what to test for:
125+
126+
1. `v1`: Just adds `version.txt` and updates the README
127+
2. `v2`: Immediately after v1, adds `new-file-in-v2`, and updates `version.txt` (all tags should have bumped versions of this)
128+
3. `v3`: Has three commits after v2, adds `another-new-file` and a non-executable script `a_script.sh`
129+
4. `v4`: Fixes the script to be executable
130+
5. `v5`: Removes `another-new-file` and moves the changelog to readme
131+
EOF
132+
133+
# Note: Despite the README saying v5 removes another-new-file, the original repo still has it at v5
134+
git rm -q CHANGELOG.md
135+
git add README.md
136+
git commit -q -m "version 5"
137+
git tag v5

tests/journey/gix.sh

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -705,21 +705,17 @@ title "gix commit-graph"
705705
)
706706

707707
if [[ "$kind" != "small" && "$kind" != "async" ]]; then
708-
# Testing repository -- TODO: Move to `GitoxideLabs` group eventually
708+
# Testing repository - local reproduction of https://github.com/staehle/gitoxide-testing
709709
testrepo_name="gitoxide-testing"
710-
testrepo_url="https://github.com/staehle/gitoxide-testing.git"
710+
# Path relative to tests/fixtures/ for use with jtt run-script
711+
testrepo_fixture_script="scripts/make_gitoxide_testing_repo.sh"
711712
# This repo has various tags with noted differences in README.md, all in form `vN`
712713
# `v5` is latest on main and should be the default cloned
713714
testrepo_v5_tag="v5"
714-
testrepo_v5_commit="6764049e6687f76f02ea3ca7c944b8cbd998edf8"
715715
testrepo_v4_tag="v4"
716-
testrepo_v4_commit="38395858a056b739ec09242115cd1c668986a594"
717716
testrepo_v3_tag="v3"
718-
testrepo_v3_commit="dea0993ab43e3b0e6d1931fe0c10a85537292930"
719717
testrepo_v2_tag="v2"
720-
testrepo_v2_commit="0ccb2debcbc3d1cac5756221cf823df14fef3094"
721718
testrepo_v1_tag="v1"
722-
testrepo_v1_commit="e60ef56eb63c866f290675e2f920792ca202054e"
723719
# This file exists in all versions, but with different content:
724720
testrepo_common_file_name="version.txt"
725721
# gix options:
@@ -735,6 +731,17 @@ title "gix clone (functional tests)"
735731
testworktree_path="${testrepo_name}-worktree"
736732

737733
(sandbox
734+
# Create/reuse the source repository using the fixture script (cached read-only)
735+
testrepo_source=$("$jtt" run-script "$root/.." "$testrepo_fixture_script")
736+
testrepo_url="file://${testrepo_source}"
737+
738+
# Resolve commit hashes from tags dynamically
739+
testrepo_v5_commit=$(cd "${testrepo_source}" && git rev-parse ${testrepo_v5_tag})
740+
testrepo_v4_commit=$(cd "${testrepo_source}" && git rev-parse ${testrepo_v4_tag})
741+
testrepo_v3_commit=$(cd "${testrepo_source}" && git rev-parse ${testrepo_v3_tag})
742+
testrepo_v2_commit=$(cd "${testrepo_source}" && git rev-parse ${testrepo_v2_tag})
743+
testrepo_v1_commit=$(cd "${testrepo_source}" && git rev-parse ${testrepo_v1_tag})
744+
738745
# Test blobless bare clone with --filter=blob:none
739746
it "creates a blobless (${gix_clone_blobless}) bare clone successfully" && {
740747
expect_run $SUCCESSFULLY "$exe_plumbing" --no-verbose clone --bare ${gix_clone_blobless} ${testrepo_url} ${testrepo_path}
@@ -797,7 +804,7 @@ title "gix clone (functional tests)"
797804
BARE_HEAD=$(cd ../${testrepo_path} && "$exe_plumbing" --no-verbose rev resolve HEAD)
798805
expect_run $SUCCESSFULLY test "$BARE_HEAD" != "$WORKTREE_HEAD"
799806
}
800-
it "HEAD should match the tag ${testrepo_v4_tag}'s commit ${testrepo_v4_commit}" && {
807+
it "HEAD should match the tag ${testrepo_v4_tag}'s commit" && {
801808
expect_run $SUCCESSFULLY test "$WORKTREE_HEAD" = "${testrepo_v4_commit}"
802809
}
803810

@@ -883,6 +890,10 @@ title "gix clone (functional tests)"
883890
testrepo_path="${testrepo_name}-bare-bloblimit"
884891

885892
(sandbox
893+
# Create/reuse the source repository using the fixture script (cached read-only)
894+
testrepo_source=$("$jtt" run-script "$root/.." "$testrepo_fixture_script")
895+
testrepo_url="file://${testrepo_source}"
896+
886897
# Test blob-limit (--filter=blob:limit=1024) bare clone
887898
it "creates a blob-limit (${gix_clone_limit}) bare clone successfully" && {
888899
expect_run $SUCCESSFULLY "$exe_plumbing" --no-verbose clone --bare ${gix_clone_limit} ${testrepo_url} ${testrepo_path}

tests/tools/src/main.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,29 @@ fn umask() -> io::Result<()> {
2222
Ok(())
2323
}
2424

25-
fn main() -> Result<(), Box<dyn std::error::Error>> {
25+
/// Run a fixture script and print the path to the resulting read-only directory.
26+
/// The directory is cached and reused across invocations.
27+
/// `cwd` - the directory to change to before running the script (should be repository root)
28+
/// `script_path` - path relative to tests/fixtures/
29+
fn run_script(cwd: PathBuf, script_path: PathBuf) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
30+
std::env::set_current_dir(&cwd)?;
31+
let fixture_path = gix_testtools::scripted_fixture_read_only_with_args(script_path, None::<String>)?;
32+
// Return absolute path since caller may be in a different directory
33+
println!("{}", cwd.join(fixture_path).display());
34+
Ok(())
35+
}
36+
37+
fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
2638
let mut args = std::env::args().skip(1);
2739
let scmd = args.next().expect("sub command");
2840
match &*scmd {
2941
"bash-program" | "bp" => bash_program()?,
3042
"mess-in-the-middle" => mess_in_the_middle(PathBuf::from(args.next().expect("path to file to mess with")))?,
43+
"run-script" => {
44+
let cwd = PathBuf::from(args.next().expect("working directory (repository root)"));
45+
let script = PathBuf::from(args.next().expect("path to script relative to tests/fixtures/"));
46+
run_script(cwd, script)?;
47+
}
3148
#[cfg(unix)]
3249
"umask" => umask()?,
3350
_ => unreachable!("Unknown subcommand: {}", scmd),

0 commit comments

Comments
 (0)