Aider-AI / aider

aider is AI pair programming in your terminal
https://aider.chat/
Apache License 2.0
21.12k stars 1.96k forks source link

Consider switching from GitPython to another package #292

Open paul-gauthier opened 1 year ago

paul-gauthier commented 1 year ago

GitPython doesn't support git repos with index version newer than v2.

https://github.com/gitpython-developers/GitPython/issues/1075

Newer versions of git can create indexes with v3 and v4:

https://git-scm.com/docs/index-format

You can work around this problem by downgrading the index format of your repo:

git update-index --index-version=2 

But it would be nice if aider used a git package that supported new index formats.

It's worth noting that dulwich currently supports v3 but not v4:

https://github.com/jelmer/dulwich/blob/master/dulwich/index.py#L309C3-L309C3

lmmx commented 3 months ago

Iā€™m not sure if perhaps pygit2 might be another option to support v3+

Edit I checked and it seems like it does indeed support a v3 and v4 index:

(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> import pygit2; r = pygit2.Repository("."); len(r.index)
13
>>>
(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 3
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> import pygit2; r = pygit2.Repository("."); len(r.index)
13
>>>
(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 4
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> import pygit2; r = pygit2.Repository("."); len(r.index)
13

I say assume: I take it the command is doing what it is supposed to. When I use GitPython it reports v2 always

(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 2
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> import git; r = git.repo.Repo("."); r.index.version
2
>>>
(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 3
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> import git; r = git.repo.Repo("."); r.index.version
2
>>>
(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 4
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> import git; r = git.repo.Repo("."); r.index.version
2

According to the format docs it should be a 4-byte integer at positions 5:8. The version is indeed changing each time (but not reliably it seems!):

(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 2
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> from pathlib import Path; int.from_bytes(Path('.git/index').read_bytes()[4:8], "big")
2
>>>
(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 3
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> from pathlib import Path; int.from_bytes(Path('.git/index').read_bytes()[4:8], "big")
2
>>>
(pygit2) louis šŸš¶ ~/dev/seven $ git update-index --index-version 4
(pygit2) louis šŸš¶ ~/dev/seven $ qp
>>> from pathlib import Path; int.from_bytes(Path('.git/index').read_bytes()[4:8], "big")
4