mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
git/revCount: improve error message when we have incomplete git history
This commit is contained in:
parent
0479db934c
commit
b1ccfaa080
4 changed files with 80 additions and 15 deletions
|
@ -322,8 +322,17 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
|
|
||||||
for (size_t n = 0; n < git_commit_parentcount(commit->get()); ++n) {
|
for (size_t n = 0; n < git_commit_parentcount(commit->get()); ++n) {
|
||||||
git_commit * parent;
|
git_commit * parent;
|
||||||
if (git_commit_parent(&parent, commit->get(), n))
|
if (git_commit_parent(&parent, commit->get(), n)) {
|
||||||
throw Error("getting parent of Git commit '%s': %s", *git_commit_id(commit->get()), git_error_last()->message);
|
throw Error(
|
||||||
|
"Failed to retrieve the parent of Git commit '%s': %s. "
|
||||||
|
"This may be due to an incomplete repository history. "
|
||||||
|
"To resolve this, either enable the shallow parameter in your flake URL (?shallow=1) "
|
||||||
|
"or add set the shallow parameter to true in builtins.fetchGit, "
|
||||||
|
"or fetch the complete history for this branch.",
|
||||||
|
*git_commit_id(commit->get()),
|
||||||
|
git_error_last()->message
|
||||||
|
);
|
||||||
|
}
|
||||||
todo.push(Commit(parent));
|
todo.push(Commit(parent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ repo=$TEST_ROOT/./git
|
||||||
|
|
||||||
export _NIX_FORCE_HTTP=1
|
export _NIX_FORCE_HTTP=1
|
||||||
|
|
||||||
rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix $TEST_ROOT/worktree $TEST_ROOT/shallow $TEST_ROOT/minimal
|
rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix $TEST_ROOT/worktree $TEST_ROOT/minimal
|
||||||
|
|
||||||
git init $repo
|
git init $repo
|
||||||
git -C $repo config user.email "foobar@example.com"
|
git -C $repo config user.email "foobar@example.com"
|
||||||
|
@ -216,18 +216,6 @@ git -C $TEST_ROOT/minimal fetch $repo $rev2
|
||||||
git -C $TEST_ROOT/minimal checkout $rev2
|
git -C $TEST_ROOT/minimal checkout $rev2
|
||||||
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit { url = $TEST_ROOT/minimal; }).rev") = $rev2 ]]
|
[[ $(nix eval --impure --raw --expr "(builtins.fetchGit { url = $TEST_ROOT/minimal; }).rev") = $rev2 ]]
|
||||||
|
|
||||||
# Fetching a shallow repo shouldn't work by default, because we can't
|
|
||||||
# return a revCount.
|
|
||||||
git clone --depth 1 file://$repo $TEST_ROOT/shallow
|
|
||||||
(! nix eval --impure --raw --expr "(builtins.fetchGit { url = $TEST_ROOT/shallow; ref = \"dev\"; }).outPath")
|
|
||||||
|
|
||||||
# But you can request a shallow clone, which won't return a revCount.
|
|
||||||
path6=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = \"file://$TEST_ROOT/shallow\"; ref = \"dev\"; shallow = true; }).outPath")
|
|
||||||
[[ $path3 = $path6 ]]
|
|
||||||
[[ $(nix eval --impure --expr "(builtins.fetchTree { type = \"git\"; url = \"file://$TEST_ROOT/shallow\"; ref = \"dev\"; shallow = true; }).revCount or 123") == 123 ]]
|
|
||||||
|
|
||||||
expectStderr 1 nix eval --expr 'builtins.fetchTree { type = "git"; url = "file:///foo"; }' | grepQuiet "'fetchTree' will not fetch unlocked input"
|
|
||||||
|
|
||||||
# Explicit ref = "HEAD" should work, and produce the same outPath as without ref
|
# Explicit ref = "HEAD" should work, and produce the same outPath as without ref
|
||||||
path7=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; }).outPath")
|
path7=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"HEAD\"; }).outPath")
|
||||||
path8=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; }).outPath")
|
path8=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; }).outPath")
|
||||||
|
|
67
tests/functional/fetchGitShallow.sh
Normal file
67
tests/functional/fetchGitShallow.sh
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# shellcheck source=common.sh
|
||||||
|
source common.sh
|
||||||
|
|
||||||
|
requireGit
|
||||||
|
|
||||||
|
# Create a test repo with multiple commits for all our tests
|
||||||
|
git init "$TEST_ROOT/shallow-parent"
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" config user.email "foobar@example.com"
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" config user.name "Foobar"
|
||||||
|
|
||||||
|
# Add several commits to have history
|
||||||
|
echo "{ outputs = _: {}; }" > "$TEST_ROOT/shallow-parent/flake.nix"
|
||||||
|
echo "" > "$TEST_ROOT/shallow-parent/file.txt"
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" add file.txt flake.nix
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" commit -m "First commit"
|
||||||
|
|
||||||
|
echo "second" > "$TEST_ROOT/shallow-parent/file.txt"
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" commit -m "Second commit" -a
|
||||||
|
|
||||||
|
echo "third" > "$TEST_ROOT/shallow-parent/file.txt"
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" commit -m "Third commit" -a
|
||||||
|
|
||||||
|
# Add a branch for testing ref fetching
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" checkout -b dev
|
||||||
|
echo "branch content" > "$TEST_ROOT/shallow-parent/branch-file.txt"
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" add branch-file.txt
|
||||||
|
git -C "$TEST_ROOT/shallow-parent" commit -m "Branch commit"
|
||||||
|
|
||||||
|
# Make a shallow clone (depth=1)
|
||||||
|
git clone --depth 1 "file://$TEST_ROOT/shallow-parent" "$TEST_ROOT/shallow-clone"
|
||||||
|
|
||||||
|
# Test 1: Fetching a shallow repo shouldn't work by default, because we can't
|
||||||
|
# return a revCount.
|
||||||
|
(! nix eval --impure --raw --expr "(builtins.fetchGit { url = \"$TEST_ROOT/shallow-clone\"; ref = \"dev\"; }).outPath")
|
||||||
|
|
||||||
|
# Test 2: But you can request a shallow clone, which won't return a revCount.
|
||||||
|
path=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = \"file://$TEST_ROOT/shallow-clone\"; ref = \"dev\"; shallow = true; }).outPath")
|
||||||
|
# Verify file from dev branch exists
|
||||||
|
[[ -f "$path/branch-file.txt" ]]
|
||||||
|
# Verify revCount is missing
|
||||||
|
[[ $(nix eval --impure --expr "(builtins.fetchTree { type = \"git\"; url = \"file://$TEST_ROOT/shallow-clone\"; ref = \"dev\"; shallow = true; }).revCount or 123") == 123 ]]
|
||||||
|
|
||||||
|
# Test 3: Check unlocked input error message
|
||||||
|
expectStderr 1 nix eval --expr 'builtins.fetchTree { type = "git"; url = "file:///foo"; }' | grepQuiet "'fetchTree' will not fetch unlocked input"
|
||||||
|
|
||||||
|
# Test 4: Regression test for revCount in worktrees derived from shallow clones
|
||||||
|
# Add a worktree to the shallow clone
|
||||||
|
git -C "$TEST_ROOT/shallow-clone" worktree add "$TEST_ROOT/shallow-worktree"
|
||||||
|
|
||||||
|
# Prior to the fix, this would error out because of the shallow clone's
|
||||||
|
# inability to find parent commits. Now it should return an error.
|
||||||
|
if nix eval --impure --expr "(builtins.fetchGit { url = \"file://$TEST_ROOT/shallow-worktree\"; }).revCount" 2>/dev/null; then
|
||||||
|
echo "fetchGit unexpectedly succeeded on shallow clone" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Also verify that fetchTree fails similarly
|
||||||
|
if nix eval --impure --expr "(builtins.fetchTree { type = \"git\"; url = \"file://$TEST_ROOT/shallow-worktree\"; }).revCount" 2>/dev/null; then
|
||||||
|
echo "fetchTree unexpectedly succeeded on shallow clone" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify that we can shallow fetch the worktree
|
||||||
|
git -C "$TEST_ROOT/shallow-worktree" rev-list --count HEAD >/dev/null
|
||||||
|
nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$TEST_ROOT/shallow-worktree\"; shallow = true; }).rev"
|
|
@ -73,6 +73,7 @@ suites = [
|
||||||
'gc-runtime.sh',
|
'gc-runtime.sh',
|
||||||
'tarball.sh',
|
'tarball.sh',
|
||||||
'fetchGit.sh',
|
'fetchGit.sh',
|
||||||
|
'fetchGitShallow.sh',
|
||||||
'fetchurl.sh',
|
'fetchurl.sh',
|
||||||
'fetchPath.sh',
|
'fetchPath.sh',
|
||||||
'fetchTree-file.sh',
|
'fetchTree-file.sh',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue