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

Running libgit2 commands #62

Closed
iliakan opened this issue Feb 2, 2023 · 29 comments
Closed

Running libgit2 commands #62

iliakan opened this issue Feb 2, 2023 · 29 comments

Comments

@iliakan
Copy link

iliakan commented Feb 2, 2023

Supercool! It actually works!

How can I run commands like:

opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
		GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
		GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;

git_status_list_new(&statuslist, g_repo, &opts);

(sorry for writing it C-style)?

P.S. This is the signature: https://libgit2.org/libgit2/#v1.5.1/group/status/git_status_list_new

P.P.S. Here's an example in this repo: https://github.com/petersalomonsen/wasm-git/blob/master/libgit2patchedfiles/examples/status.c

Also, is it possible to access repository tree, e.g. I want to test the repository structure, tree of commits, in my code.

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

It seems that this whole compilation project only allows to call the main function of lg2.c, and there's no way to call any other methods.

Please correct me if I'm mistaken.

@petersalomonsen
Copy link
Owner

Yeah the current approach to it is that you can run all the libgit2 examples which are a "mixture of basic emulation of core Git command line functions and simple snippets demonstrating libgit2 API usage".

However I've actually added a few more than the ones included with libgit2, which you can find here: https://github.com/petersalomonsen/wasm-git/tree/master/libgit2patchedfiles/examples

I would suggest that you build on / add more on these to extend with the functionality that you need.

In recent versions of libgit2 there's also a CLI. My plan is at some point to switch to this ( or add it ).

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

So if I want to call other libgit2 functions, then I need to build upon wasm-git?

For instance, what should be my steps if I need to call git_status_list_new ?

P.S. I tried libgit2 CLI yesterday, it's more like a POC. There are literally few commands.

@petersalomonsen
Copy link
Owner

Yes you should add more to the libgit2patchedfiles/examples folder.

Regarding git_status_list_new you can already see that it's called in https://github.com/petersalomonsen/wasm-git/blob/master/libgit2patchedfiles/examples/status.c#L102

Thanks for the info on CLI status, I haven't really tested it yet, but it's probably better then to wait until it's a bit more mature.

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

Are these examples somehow linked into lg2.js?

@petersalomonsen
Copy link
Owner

yes they are! if you add into there, it should be automatically linked. You can also add more commands here: https://github.com/petersalomonsen/wasm-git/blob/master/libgit2patchedfiles/examples/lg2.c#L12

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

Are many of them in fact your own?

E.g. this one: https://github.com/petersalomonsen/wasm-git/blob/master/libgit2patchedfiles/examples/reset.c
I couldn't find the same in libgit2 ;)

@petersalomonsen
Copy link
Owner

Yeah all of these in this repository are mine.

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

I came across a fairly old comment isomorphic-git/isomorphic-git#268 (comment)

Yep. Compilation with emscripten works. But there are lots of edgecases that don't. Anything that touches mmap syscall fails. The emscripten fs is a spaghetti and too deeply embedded (and a requirement for me to be able to interop with other js code that uses fs).

How valid is it nowadays?

I'm especially concerned with "edgecases" that don't work (anything that touches mmap?).
Is there something in libgit2 that won't work?

@petersalomonsen
Copy link
Owner

I did fix the mmap issues in emscripten as you can see here: https://github.com/petersalomonsen/wasm-git#building

As you can see I did 3 Pull Requests to the emscripten repository to fix the mmap issues.

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

Cool! So you don't foresee any problems? ;)

Asking that just in case, to know what to expect.

@petersalomonsen
Copy link
Owner

No, at this point I don't know of anything specific in libgit2 that shouldn't work. There may be of course limitation on very large repositories, both that it would be slower, and also because of limitations of the size of http payloads, but I don't know about any functional issues.

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

Let's say I want to improve examples, add new functions.

Is there an easy way to compile and test those directly, not involving wasm recompilation?

P.S. My C skills are coming from 20 years ago student experience. But this was a good experience, so I remember how to code ;)

@petersalomonsen
Copy link
Owner

you need to recompile the wasm, but there is a setup already for gitpod so that you should have all the tools needed to recompile.

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

These are C files... maybe I can test in libgit2 environment?

@petersalomonsen
Copy link
Owner

you can of course test in libgit2, but you will get the full experience ( in the browser or node ) if you compile with emscripten. Also I would add some testcode for testing your additions like this for nodejs ( there are also tests for the browser ):

https://github.com/petersalomonsen/wasm-git/blob/master/test/checkout.spec.js

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

Let's say I want status as JS object.

How can I achieve that? Should I implement a new command and use JSON-encoder in C, or there's an easier way?

@petersalomonsen
Copy link
Owner

you can also just in JS encode the result received from C, but it depends on how/what you want to extract from the output

@iliakan
Copy link
Author

iliakan commented Feb 3, 2023

E.g. this line from status.c:

    check_lg2(git_status_list_new(&status, repo, &o.statusopt),
              "Could not get status", NULL);

I'd like to get the resulting status structure in JS. Can I pass it directly?

@petersalomonsen
Copy link
Owner

If you want to be aligned with future updates of wasm-git I would recommend that you write separate command files for your own extensions ( and not modify status.c unless actually improving it to be closer to real git cli ).

But if you want to add your own command and output a javascript object, you should look into emscripten features for calling JS from C which is described here: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#calling-javascript-from-c-c

@iliakan
Copy link
Author

iliakan commented Feb 4, 2023

I see ccall and cwrap examples at https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-ccall-cwrap

Maybe it's possible to call libgit2 functions directly using them, without lg2.callMain and without making a new example?

@petersalomonsen
Copy link
Owner

yeah if you annotate a function with EMSCRIPTEN_KEEPALIVE ( https://emscripten.org/docs/api_reference/emscripten.h.html?highlight=emscripten_keepalive#c.EMSCRIPTEN_KEEPALIVE ) you can call it without implementing a new example.

@iliakan
Copy link
Author

iliakan commented Feb 4, 2023

annotate? that is, by modifying libgit2? ;)

@petersalomonsen
Copy link
Owner

no, rather add a new c file in wasm-git that contains a function that calls libgit2. You need to expose them somehow. ccall / cwrap expects the functions to be exported in the webassembly file.

@iliakan
Copy link
Author

iliakan commented Feb 4, 2023

so I could, like, create an export.c file with all the functions I want to export from libgit2 and call them directly? ;)

@petersalomonsen
Copy link
Owner

yes that should work. just remember to include it in the compilation.

@iliakan
Copy link
Author

iliakan commented Feb 5, 2023

A simple function, such as int_sqrt seems to work (with added compilation flags).

Although doing git init doesn't work.

Please take a look here: #64.

P.S. I hope I'm calling the function correctly.
P.P.S. Please, help ;)

@petersalomonsen
Copy link
Owner

I think you need to look in here on how to initialize a repo: https://github.com/libgit2/libgit2/blob/main/examples/init.c#L45
And here: https://github.com/libgit2/libgit2/blob/main/examples/lg2.c#L70

There's a lot more involved into using libgit2, you cannot just call one of the library methods alone, you also have to init and shutdown libgit2. Some good documentation is also here: https://libgit2.org/docs/guides/101-samples/

If building on the examples codebase you get a lot of the initialization code out of the box.

@iliakan
Copy link
Author

iliakan commented Feb 7, 2023

Oh, indeed I overlooked that call.
Now the initialization works as it should.

Thank you for the help!

@iliakan iliakan closed this as completed Feb 7, 2023
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

2 participants