Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot get commits in code, but it works in REPL? #1121

Closed
SwampFalc opened this issue Feb 9, 2021 · 6 comments
Closed

Cannot get commits in code, but it works in REPL? #1121

SwampFalc opened this issue Feb 9, 2021 · 6 comments
Labels

Comments

@SwampFalc
Copy link

I'm trying to write a pre-receive hook.

When using the repl, I get the following results:

>>> from git import Repo
>>> repo = Repo(".")
>>> repo.git_dir
'/home/ldt/Projects/dns/dns/.git'
>>> repo.head.abspath
'/home/ldt/Projects/dns/dns/.git/HEAD'
>>> repo.head.commit
<git.Commit "f9b9455e3cc3152a81dc1da30c9bf3b0ed5eb127">

Here is the relevant content of my pre-receive hook file:

from git import Repo

repo = Repo("/home/ldt/Projects/dns/dns/.git")
print(repo.git_dir)
print(repo.head.abspath)
print(repo.head.commit)

However, when I trigger this with a push, this is the result:

Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 4 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 876 bytes | 876.00 KiB/s, done.
Total 9 (delta 6), reused 0 (delta 0)
remote: /home/ldt/Projects/dns/dns/.git
remote: /home/ldt/Projects/dns/dns/.git/HEAD
remote: Traceback (most recent call last):
remote:   File "hooks/pre-receive", line 11, in <module>
remote:     print(repo.head.commit)
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/refs/symbolic.py", line 197, in _get_commit
remote:     obj = self._get_object()
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/refs/symbolic.py", line 190, in _get_object
remote:     return Object.new_from_sha(self.repo, hex_to_bin(self.dereference_recursive(self.repo, self.path)))
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/objects/base.py", line 64, in new_from_sha
remote:     oinfo = repo.odb.info(sha1)
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/db.py", line 37, in info
remote:     hexsha, typename, size = self._git.get_object_header(bin_to_hex(sha))
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/cmd.py", line 1074, in get_object_header
remote:     return self.__get_object_header(cmd, ref)
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/cmd.py", line 1063, in __get_object_header
remote:     return self._parse_object_header(cmd.stdout.readline())
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/cmd.py", line 1025, in _parse_object_header
remote:     raise ValueError("SHA could not be resolved, git returned: %r" % (header_line.strip()))
remote: ValueError: SHA could not be resolved, git returned: b''

I don't get it... How could it work in the REPL but not in code? Could there be some sort of difference in the shell environment that GitPython uses? But if so, what?

@SwampFalc
Copy link
Author

Further digging has revealed that the problem indeed lies in the fact that, when the hook runs the code, cmd.stdout.readline() just returns a blank...
Whether this is due to the shell environment, or maybe because of the state of the repo at the moment of the pre-receive hook, I cannot tell.

@Byron
Copy link
Member

Byron commented Feb 11, 2021

To me it looks like git is failing when executed from the context of the hook script. My recommendation is to turn on more advanced debugging to learn more.

My expectation would be that the above works though.

@SwampFalc
Copy link
Author

OK, so I put the same code into a pre-commit hook and that did not fail. So that makes it pretty obvious to me that it is not the shell environment, but rather the state of the repository during the pre-receive hook that is at fault.

I have tried the debugging settings, but unfortunately, it seems this particular command does not get debugged properly:

Total 9 (delta 6), reused 0 (delta 0), pack-reused 0
remote: INFO:git.cmd:git version -> 0; stdout: 'git version 2.30.0'
remote: INFO:git.cmd:git version -> 0; stdout: 'git version 2.30.0'
remote: INFO:git.cmd:git cat-file --batch-check
remote: /home/ldt/Projects/dns/dns/.git
remote: /home/ldt/Projects/dns/dns/.git/HEAD
remote: Traceback (most recent call last):
remote:   File "hooks/pre-receive", line 14, in <module>
remote:     print(repo.head.commit)
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/refs/symbolic.py", line 197, in _get_commit
remote:     obj = self._get_object()
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/refs/symbolic.py", line 190, in _get_object
remote:     return Object.new_from_sha(self.repo, hex_to_bin(self.dereference_recursive(self.repo, self.path)))
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/objects/base.py", line 64, in new_from_sha
remote:     oinfo = repo.odb.info(sha1)
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/db.py", line 37, in info
remote:     hexsha, typename, size = self._git.get_object_header(bin_to_hex(sha))
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/cmd.py", line 1079, in get_object_header
remote:     return self.__get_object_header(cmd, ref)
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/cmd.py", line 1067, in __get_object_header
remote:     return self._parse_object_header(out)
remote:   File "/home/ldt/.virtualenvs/dns-0cwPatsd-py3.8/lib/python3.8/site-packages/git/cmd.py", line 1027, in _parse_object_header
remote:     raise ValueError("SHA could not be resolved, git returned: %r" % (header_line.strip()))
remote: ValueError: SHA could not be resolved, git returned: b''
To ../dns/.git

As you can see, some early git commands do get logged but not the one that gives no output...

Something else I tried was putting the repo into the pre-receive state by making a pre-receive hook that just looped infintely (while True: pass) and then open the REPL besides it. I was hoping to find the same error but that just works...

@Byron
Copy link
Member

Byron commented Feb 11, 2021

Thanks for the heads-up. Since it's something with the way GitPython obtains object information, you could try to instantiate the repository with a different object database implementation.

The one implemented in pure python would certainly provide better error messages, maybe it works even.

Something I can imagine to be the reason for this issue in the first place is a different run environment, as the git command is influenced by plenty of environment variables which are set in hooks only.

@SwampFalc
Copy link
Author

Well now, using the GitDB object database does work!

As for the environment, I did dump os.environ from both use cases once before, but I was more looking for things affecting my shell (I once had a bug in another tool involving the IFS...). But here they are, sorted for easy diffing:

codes.txt
repls.txt

@Byron
Copy link
Member

Byron commented Feb 12, 2021

Thanks again! Please allow me nonetheless to close this issue as answered question due to the discovery of a workaround. Hopefully people will be able to find it when encountering similar issues.

In order to reopen, there should be script(s) to make this issue reproducible.

@Byron Byron closed this as completed Feb 12, 2021
@Byron Byron reopened this Feb 26, 2021
@Byron Byron closed this as completed Feb 26, 2021
@gitpython-developers gitpython-developers locked and limited conversation to collaborators Feb 26, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Development

No branches or pull requests

2 participants