pygit2 icon indicating copy to clipboard operation
pygit2 copied to clipboard

pygit2.GitError: no error

Open hramrach opened this issue 1 year ago • 24 comments

Traceback (most recent call last): File "/home/hramrach/kbuild/python/tests/test_branch_graph.py", line 32, in setUp self.repo.lookup_branch(branch).set_target(commit) _pygit2.GitError: no error

???

hramrach avatar Sep 05 '24 13:09 hramrach

import pygit2
from pygit2.enums import FileMode
from pathlib import Path
import tempfile
import shutil
import sys

print(f"python: {sys.version}")
print(f"libgit2: {pygit2.LIBGIT2_VERSION}")
print(f"pygit2: {pygit2.__version__}")

data = {
'longterm': '6.6',
'master': '6.11-rc6',
'stable': '6.10',
}

base = Path(tempfile.mkdtemp())

repo = pygit2.init_repository(base, bare=True)
sig = pygit2.Signature('Test User', '[email protected]')
commit = None
for branch in data:
    tree = repo.TreeBuilder()
    version = data[branch]
    tree.insert('version', repo.create_blob(version.encode()), FileMode.BLOB)
    commit = repo[repo.create_commit('HEAD', sig, sig, f'{branch} commit', tree.write(), [commit.id] if commit else [])]
    if branch == 'master':
        try:
            repo.lookup_branch(branch).set_target(commit)
        except pygit2.GitError as e:
            print(repr(e))
            None
    else:
        repo.branches.local.create(branch, commit)

shutil.rmtree(base, ignore_errors=True)
python: 3.11.9 (main, Apr 18 2024, 16:44:43) [GCC]
libgit2: 1.8.0
pygit2: 1.14.1
GitError('no error')

hramrach avatar Sep 06 '24 12:09 hramrach

Is your issue about your code not working or about the error message?

About the message, if you clone the repo and do a lookup of that string ("no error") you'll see this:

Image

So it's not all that surprising. It's what I get too if I remove your try/except.

Image

Tsafaras avatar Feb 19 '25 20:02 Tsafaras

Like what does exception saying "No error" mean?

Shouldn't GIT_OK not throw an exception?

Is this supposed to work or not?

hramrach avatar Feb 20 '25 20:02 hramrach

Can you try again with latest version of pygit2? Maybe your problem's addressed just by upgrading.

Tsafaras avatar Feb 22 '25 12:02 Tsafaras

python: 3.11.11 (main, Dec 06 2024, 17:06:18) [GCC] libgit2: 1.9.0 pygit2: 1.17.0 GitError('no error')

hramrach avatar Feb 23 '25 13:02 hramrach

I am a bit confused on what the actual issue is.

Are you trying to set up a script to achieve a certain goal? If so, you should provide a full reproducible example. I personally can't help you, otherwise,

Tsafaras avatar Feb 26 '25 18:02 Tsafaras

I am trying to fabricate a repository. There are a number of ways to go about that, and the documentation is not clear enough to be able to pick one sure way that would certainly work.

One of the ways that can be picked results in pygit2 throwing very unhelpful "No error" exception.

Either there is a bug that something that should have actually worked does not, or there is a bug that something that failed fails to propagate the failure reason somewhere.

In any case this sounds like a situation that is broken either way, it's just not clear which way.

hramrach avatar Feb 26 '25 19:02 hramrach

I am trying to fabricate a repository.

Can you show the equivalent in bash commands?

mkdir new-repo
cd new-repo
git init

Something like that...

Tsafaras avatar Feb 27 '25 12:02 Tsafaras

git init new-repo cd new-repo echo 6.6 > version git add version git commit -m longterm\ commit version git branch longterm echo 6.10 > version git commit -m stable\ commit version git branch stable echo 6.11-rc6 > version git commit -m master\ commit version

hramrach avatar Feb 27 '25 12:02 hramrach

Note this is not completely equivalent because the API for updating branches does not match commandline.

The problem seems to be that updating unborn branch is broken.

hramrach avatar Feb 27 '25 12:02 hramrach

Can we first settle on what you want to accomplish? Because the commands you gave don't run successfully.

I am assuming this is the full logic? Corrected for some commands and included some more. You left it as an exercise for the reader? 😂

git init new-repo
cd new-repo
echo 6.6 > version
# The file is not yet tracked by git. You can't just `git commit ..`.
git add version # Or `git add .`; makes no difference here.
# Need quotes around the message.
git commit -m "added version"
# You remain on main branch in your example.
git switch -c longterm
echo 6.10 > version
# Now you can commit the file without even staging it.
# Still need quotes around the message though.
git commit -m "added version" version

# The rest makes no difference... so let's ignore it.

Tsafaras avatar Feb 27 '25 18:02 Tsafaras

right, you need to add the version file

hramrach avatar Feb 27 '25 18:02 hramrach

and no, this does not involve switch.

hramrach avatar Feb 27 '25 18:02 hramrach

The difference between the commandline and the libgit implementation is that the commandline advances the master branch multiple times while the libgit2 implementation probably does not, or would not if it worked.

hramrach avatar Feb 27 '25 18:02 hramrach

Note that the stacking of the branches may not be the same because the 'data' hash does not list them from oldest to newest but whatever.

hramrach avatar Feb 27 '25 18:02 hramrach

and no, this does not involve switch.

So you want to commit the changes to the version file in main? If so, what's the point of creating the new branch then? 🤔

Tsafaras avatar Feb 27 '25 18:02 Tsafaras

I want to create three different branches, each with different content in the version file.

It's difficult and unrealistic to make them all separate history roots so the different commits to which the branches point have to be in the same history.

hramrach avatar Feb 27 '25 18:02 hramrach

But you can't commit to a branch, unless you're "on it". At least not without jumping through hoops. So how do you do that without switching to it?

And if for some reason you absolutely want to have a new branch start with its own history, there's this option

git switch --orphan <new branch name>

Tsafaras avatar Feb 27 '25 19:02 Tsafaras

I can create a branch from the current commit, both on commandline and in libgit, no need to switch to it, or commit to it.

hramrach avatar Feb 27 '25 19:02 hramrach

In fact I have no idea how I would 'commit to a branch' in libgit.

hramrach avatar Feb 27 '25 19:02 hramrach

I'm even more lost now because I see contradicting statements. Can you provide the commands that someone should follow blindly? Just a copy-paste and it would have the outcome you want.

Tsafaras avatar Feb 27 '25 19:02 Tsafaras

So one way that works is

master = repo.create_commit('HEAD', sig, sig, 'master commit', tree.write(), []) repo.lookup_branch('master').set_target(master) stable = repo[master] repo.branches.local.create('stable', stable) stable = repo.create_commit('refs/heads/stable', sig, sig, 'stable commit', tree.write(), [master])

which is quite awkward, and it's non-obvious why this would work, and the other way throws an exception. Also it creates the branches backwards, stable ahead of master. Which does not really matter in this case but is another awkward result of randomly trying things until something sticks because there is no clear description of what should work, nor a clear description of why things that don't work don't.

hramrach avatar Feb 27 '25 19:02 hramrach

git init new-repo cd new-repo echo 6.6 > version git add version git commit -m longterm\ commit version git branch longterm echo 6.10 > version git commit -m stable\ commit version git branch stable echo 6.11-rc6 > version git commit -m master\ commit version

hramrach avatar Feb 27 '25 20:02 hramrach

import pygit2
from pygit2.enums import FileMode
from pathlib import Path
import tempfile
import shutil
import sys

print(f"python: {sys.version}")
print(f"libgit2: {pygit2.LIBGIT2_VERSION}")
print(f"pygit2: {pygit2.__version__}")

data = {
'longterm': '6.6',
'stable': '6.10',
'master': '6.11-rc6',
}

base = Path(tempfile.mkdtemp())

repo = pygit2.init_repository(base, bare=True)
sig = pygit2.Signature('Test User', '[email protected]')
commit = None
for branch in data:
    tree = repo.TreeBuilder()
    version = data[branch]
    tree.insert('version', repo.create_blob(version.encode()), FileMode.BLOB)
    commit = repo[repo.create_commit('HEAD', sig, sig, f'{branch} commit', tree.write(), [commit.id] if commit else [])]
    if branch == 'master':
        try:
            repo.lookup_branch(branch).set_target(commit)
        except pygit2.GitError as e:
            print(repr(e))
            None
    else:
        repo.branches.local.create(branch, commit)

shutil.rmtree(base, ignore_errors=True)

hramrach avatar Feb 27 '25 20:02 hramrach

python: 3.13.5 (main, Jun 12 2025, 00:40:24) [GCC] libgit2: 1.9.0 pygit2: 1.17.0 GitError('no error')

hramrach avatar Sep 05 '25 09:09 hramrach