You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
git_index_add_bypath accepts a path beyond a symbolic link, where git add refuses #7380
git refuses a pathspec whose non-final component is a symlink; git_index_add_bypath accepts it.
git init r &&cd r
mkdir realdir &&echo hi > realdir/file.txt
ln -s realdir linkdir
git add linkdir/file.txt
# fatal: pathspec 'linkdir/file.txt' is beyond a symbolic link
libgit2 1.9.7
git_index_add_bypath("linkdir/file.txt") -> 0 (accepted)
index entry present: linkdir/file.txt
Committing that index produces a tree git cannot reconcile:
$ git ls-tree -r HEAD
100644 blob 45b983be... linkdir/file.txt
$ git fsck # clean
$ git status --porcelain
D linkdir/file.txt
?? linkdir
The path is in the commit, fsck is happy, and git reports it deleted, because git will not walk through the symlink to find it. A checkout of that commit has to create linkdir as a directory, so the symlink the repository also tracks and the committed path cannot both exist.
Expected behavior
git_index_add_bypath rejects a path whose non-final component is a symlink, as git add does.
Actual behavior
It is accepted and an index entry is created at the literal path.
Version of libgit2 (release number or SHA1)
1.9.7
Operating system(s) tested
macOS 26.6, arm64. Reproduced with a C program linked against libgit2 directly; originally found through pygit2 in libgit2/pygit2#1375, where @calestyo asked for it to be raised here.
One related asymmetry from that thread, in case it bears on where the check belongs: git_index_add_all with the same path adds nothing and returns success, so the two entry points already disagree with each other as well as with git.
I have not checked whether this is deliberate — docs/differences-from-git.md does not mention it, but "libgit2 is not a pathspec parser" is a reasonable position and would make this a documentation note instead.
Filed by Claude Opus 5 (Claude Code) running under my account; the reproduction above was compiled and run rather than reasoned about.
Activity
calestyo commentedon Sep 19, 2026
Back when I found this in pygit2 I've wondered whether this might be abused in some form, though I didn't really come to a conclusion.