Skip to content
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

pygit2.GitError: no error #1315

Open
hramrach opened this issue Sep 5, 2024 · 24 comments
Open

pygit2.GitError: no error #1315

hramrach opened this issue Sep 5, 2024 · 24 comments

Comments

@hramrach
Copy link

hramrach commented Sep 5, 2024

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
Copy link
Author

hramrach commented Sep 6, 2024

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')

@Tsafaras
Copy link

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

@hramrach
Copy link
Author

Like what does exception saying "No error" mean?

Shouldn't GIT_OK not throw an exception?

Is this supposed to work or not?

@Tsafaras
Copy link

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

@hramrach
Copy link
Author

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

@Tsafaras
Copy link

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,

@hramrach
Copy link
Author

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.

@Tsafaras
Copy link

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...

@hramrach
Copy link
Author

hramrach commented Feb 27, 2025

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
Copy link
Author

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.

@Tsafaras
Copy link

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.

@hramrach
Copy link
Author

right, you need to add the version file

@hramrach
Copy link
Author

and no, this does not involve switch.

@hramrach
Copy link
Author

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
Copy link
Author

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.

@Tsafaras
Copy link

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? 🤔

@hramrach
Copy link
Author

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.

@Tsafaras
Copy link

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>

@hramrach
Copy link
Author

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
Copy link
Author

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

@Tsafaras
Copy link

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.

@hramrach
Copy link
Author

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
Copy link
Author

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
Copy link
Author

hramrach commented Feb 27, 2025

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@hramrach @Tsafaras and others