-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
According to the documentation and a pre-existing test (test_revwalk_basic__glob_heads_with_invalid), git_revwalk_push_glob should ignore references that are included by the glob but do not point to a commit, instead of returning an error. However, the situation where a dangling symbolic reference (ie a symbolic reference pointing to a non-existing reference) is included by the glob is not being handled gracefully, and an error is returned.
This was detected as part of another problem, when running a fetch operation with pruning on a repository whose HEAD changed from master to main twice fails the second time, since the fetch negotiation uses a revwalk (and git_revwalk_push_glob). For the record, these were the steps for that:
- Create a remote repository where the default branch (and HEAD) is
master. - Clone that remote to a local repository.
- On the remote, rename
mastertomain(git branch -m master main). Make sure theHEADreference on the remote itself changes tomainas well. - Using libgit2, run a fetch operation on the local clone created on step 2 with pruning turned on. This should go through, remove the remote's
masterreference and addmain(not sure what happens exactly if you havemasterchecked out, adjust if needed for the remote'smasterto be removed). Make sure/refs/remotes/<remote-name>/HEADstill points tomaster, as expected (if the equivalent core git operation is performed, git warns the remote HEAD turned into a dangling reference). - Add a few commits to the remote from another clone (this step is necessary because, in the following step, libgit2 is too smart and wont actually enter the negotiation phase if it knows there's nothing to fetch).
- Repeat step 4 (run a fetch operation on the local clone created on step 2 with pruning turned on).
An error will be thrown saying refs/remotes/<remote-name>/master does not exist.
Reproduction steps
Regarding the root issue this ticket addresses, the following code will fail with an error (-1) when it should succeed:
revwalk_basic_setup_walk("testrepo");
cl_git_mkfile("testrepo/.git/refs/heads/broken-sym-ref", "ref: refs/heads/does-not-exist");
cl_git_pass(git_revwalk_push_glob(_walk, "heads"));
Expected behavior
The broken reference should be ignored and not cause an error.
Actual behavior
An error is thrown (refs/remotes/<remote-name>/master does not exist.).
Version of libgit2 (release number or SHA1)
main (a3841af5eecc6301e87f8302c7fdce6555e39247)
Operating system(s) tested
macOS (13.0).