Skip to content

index: write blobs via git hash-object, not gitdb's odb.store - #2209

Open
caroescm wants to merge 1 commit into
gitpython-developers:mainfrom
caroescm:fix-index-add-chmod
Open

index: write blobs via git hash-object, not gitdb's odb.store#2209
caroescm wants to merge 1 commit into
gitpython-developers:mainfrom
caroescm:fix-index-add-chmod

Conversation

@caroescm

Copy link
Copy Markdown

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:

  • No more Python-side chmod, so the crash goes away.
  • The stored content now matches what git add would store, filters included.

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

  • Ran the existing test suite (test_index.py, test_base.py, test_repo.py) — all still pass.
  • Compared index.add()'s output to real git add for a normal file, a symlink, and a file in a subfolder — identical results.
  • Recreated the original bug by blocking chmod only on .git/objects files (same as the error in repo.index.add() method attempts to chmod files which it should not #2021) — index.add() now works instead of crashing.

@caroescm
caroescm force-pushed the fix-index-add-chmod branch from 4dbefc1 to 7ab02c6 Compare August 10, 2026 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

repo.index.add() method attempts to chmod files which it should not

1 participant