Closed iliakan closed 1 year ago
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.
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 ).
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.
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.
Are these examples somehow linked into lg2.js?
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
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 ;)
Yeah all of these in this repository are mine.
I came across a fairly old comment https://github.com/isomorphic-git/isomorphic-git/issues/268#issuecomment-395610965
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?
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.
Cool! So you don't foresee any problems? ;)
Asking that just in case, to know what to expect.
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.
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 ;)
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.
These are C files... maybe I can test in libgit2 environment?
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
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?
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
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?
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
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?
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.
annotate? that is, by modifying libgit2? ;)
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.
so I could, like, create an export.c
file with all the functions I want to export from libgit2 and call them directly? ;)
yes that should work. just remember to include it in the compilation.
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: https://github.com/petersalomonsen/wasm-git/pull/64.
P.S. I hope I'm calling the function correctly. P.P.S. Please, help ;)
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.
Oh, indeed I overlooked that call. Now the initialization works as it should.
Thank you for the help!
Supercool! It actually works!
How can I run commands like:
(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.