| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
Thanks a lot for tackling this! I will see if an alternative solution can do the trick, as such a localized override goes against the original architecture. |
Sorry, something went wrong.
This is done by calling into `git hash-object` for correctness, instead of using a mostly incorrect custom implementation for this (lacks filters). <!-- agent --> GitCmdObjectDB inherited LooseObjectDB.store(), so despite its name, object writes bypassed Git and used gitdb's loose-object implementation. That path creates and chmods object files itself, which can fail during Index.add() on filesystems where those permission changes are unsupported. Override store() to stream new objects through `git hash-object -w --stdin`. This lets Git manage object creation and permissions consistently with the repository configuration. Retain the inherited implementation for pre-hashed objects and custom output streams, whose existing semantics hash-object cannot provide. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 <codex@openai.com>
| Back | FazBrowse Home | New Git URL |
Problem
repo.index.add() is GitPython's own way of adding files, separate from just running git add. To do that, it writes the file's content into .git/objects itself using Python, instead of asking git to do it. As part of that, it also tries to change the new file's permissions (chmod) — and in some setups, that permission change isn't allowed, even though writing the file itself worked fine.
So index.add() can crash with PermissionError in situations where plain git add (and repo.git.add(...), which just runs git add directly) work without any problem, on the same file.
There's also a smaller side effect: because GitPython reads the file itself instead of asking git, it skips any .gitattributes rules (like converting line endings), so the content it stores can end up slightly different from what git add would store.
What I changed
I changed index.add() to use the real git hash-object -w command to write the file into the object database, instead of doing it in Python. This means:
Symlinks needed a small extra step: git hash-object normally follows a symlink and hashes the file it points to, but Git is supposed to store the symlink's target path itself, not the pointed-to file. So for symlinks, I write the target path to a temporary file and hash that instead.
Fixes #2021
Testing