Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM ubuntu:latest

RUN apt-get update && apt-get install -y \
build-essential \
curl \
wget \
cmake \
dos2unix \
git \
nodejs \
npm \
nano \
sudo \
apt-transport-https \
ca-certificates \
software-properties-common

WORKDIR /src

RUN git clone https://github.com/emscripten-core/emsdk.git && \
/src/emsdk/emsdk install latest && \
/src/emsdk/emsdk activate latest
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,28 @@ for using with `NODEFS` you'll also need https://github.com/emscripten-core/emsc

All of these pull requests are merged to emscripten master as of 2020-03-29.

See [.github/workflows/main.yml](./.github/workflows/main.yml) for a full build and test pipeline including installing emscripten.

Run [setup.sh](setup.sh) first to download libgit2 and apply patches.

Given you have installed and activated emscripten, you can use the script in [emscriptenbuild/build.sh](emscriptenbuild/build.sh) to configure and build, and you'll find the resulting `lg2.js` / `lg2.wasm` under the generated `emscriptenbuild/examples` folder.

An example of interacting with libgit2 from nodejs can be found in [examples/example_node.js](examples/example_node.js).

An example for the browser (using webworkers) can be found in [examples/example_webworker.js](examples/example_webworker.js). You can start a webserver for this by running the [examples/webserverwithgithubproxy.js](examples/webserverwithgithubproxy.js) script, which will launch a http server at http://localhost:5000 with a proxy to github. Proxy instead of direct calls is needed because of CORS restrictions in a browser environment.

## Docker build

Build image in repository directory:

```bash
docker build -t wasm-git-image .
```

Example Release build and SINGLE_FILE parameter:

```bash
docker run -v .:/src/wasm-git --rm wasm-git-image /bin/bash -c "cd /src/wasm-git && git ls-files | xargs dos2unix && /src/wasm-git/docker_cleanup_and_build.sh Release SINGLE_FILE"
```

After build outputs can be found in emscriptenbuild/libgit2/examples/lg2.js and and in case no SINGLE_FILE parameter was provided also emscriptenbuild/libgit2/examples/lg2.wasm.
14 changes: 14 additions & 0 deletions docker_cleanup_and_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cd /src/wasm-git
rm -rf libgit2
rm -rf emscriptenbuild/libgit2
rm -rf emscriptenbuild/CMakeFiles
rm -f emscriptenbuild/lg2.wasm
rm -f emscriptenbuild/lg2.js
rm -f emscriptenbuild/cmake_install.cmake
rm -f emscriptenbuild/CMakeCache.txt
rm -f emscriptenbuild/Makefile
npm install
sh setup.sh
source /src/emsdk/emsdk_env.sh
cd /src/wasm-git/emscriptenbuild
./build.sh "$@"
11 changes: 10 additions & 1 deletion emscriptenbuild/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,17 @@ elif [ "$1" == "Debug-async" ]; then
export LG2_OUTPUT_NAME=lg2_async
fi

# Check if output should be bundled in a single js file
for param in "$@"; do
# Check if the parameter is 'abc'
if [ "$param" == "SINGLE_FILE" ]; then
EXTRA_CMAKE_C_FLAGS="${EXTRA_CMAKE_C_FLAGS} -s SINGLE_FILE"
break
fi
done

# Before building, remove any ../libgit2/src/ transports/emscriptenhttp.c left from running setup.sh
[ -f "../libgit2/src/libgit2/transports/emscriptenhttp-async.c" ] && rm ../libgit2/src/libgit2/transports/emscriptenhttp-async.c

emcmake cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_C_FLAGS="$EXTRA_CMAKE_C_FLAGS --pre-js $(pwd)/pre.js $POST_JS -s \"EXPORTED_RUNTIME_METHODS=['FS','MEMFS','IDBFS','NODEFS','callMain']\" -sFORCE_FILESYSTEM -sEXPORT_ES6 -s INVOKE_RUN=0 -s ALLOW_MEMORY_GROWTH=1 -s STACK_SIZE=131072 -lidbfs.js -lnodefs.js" -DREGEX_BACKEND=regcomp -DSONAME=OFF -DUSE_HTTPS=OFF -DBUILD_SHARED_LIBS=OFF -DTHREADSAFE=OFF -DUSE_SSH=OFF -DBUILD_CLAR=OFF -DBUILD_EXAMPLES=ON ..
emcmake cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_C_FLAGS="$EXTRA_CMAKE_C_FLAGS --pre-js $(pwd)/pre.js $POST_JS -s \"EXPORTED_RUNTIME_METHODS=['FS','MEMFS','IDBFS','NODEFS','callMain']\" -sFORCE_FILESYSTEM -sEXPORT_ES6 -sINVOKE_RUN=0 -sALLOW_MEMORY_GROWTH=1 -sSTACK_SIZE=5MB -lidbfs.js -lnodefs.js -flto" -DREGEX_BACKEND=regcomp -DSONAME=OFF -DUSE_HTTPS=OFF -DBUILD_SHARED_LIBS=OFF -DTHREADSAFE=OFF -DUSE_SSH=OFF -DBUILD_CLAR=OFF -DBUILD_EXAMPLES=ON ..
emmake make lg2
2 changes: 2 additions & 0 deletions emscriptenbuild/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
const emscriptenhttpconnections = {};
let httpConnectionNo = 0;

var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};

if(ENVIRONMENT_IS_WORKER) {
Object.assign(Module, {
emscriptenhttpconnect: function(url, buffersize, method, headers) {
Expand Down
12 changes: 12 additions & 0 deletions emscriptenbuild/pre.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
Object.assign(Module, globalThis.wasmGitModuleOverrides);

// Add HTTP Basic auth headers
if (Module.username || Module.accessToken) {
XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
this._open(method, url, async, user, password);
if (Module.accessToken) {
const username = Module.username || '';
this.setRequestHeader('Authorization', `Basic ${btoa(username + ':' + Module.accessToken)}`);
}
};
}

if (!Module.print && !Module.printErr) {
let capturedOutput = null;
let capturedError = null;
Expand Down
137 changes: 137 additions & 0 deletions libgit2patchedfiles/examples/branch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* libgit2 "branch" example - Get local / remote branch list and delete a local branch.
*
* Written by the libgit2 contributors
*
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication along
* with this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/

#include "common.h"

/**
* The following example demonstrates how to list and delete branches with libgit2.
*
* It will use the repository in the current working directory and list local branches by default, but also allows deleting local branches and list remote branches with options.
*
* Recognized options are:
* -r: list remote branches.
* -d <branch_name>: delete local branch.
*/

typedef struct {
int list : 1;
int remote : 1;
int delete : 1;
char* branch_name;
} branch_options;

static void print_usage(void)
{
fprintf(stderr, "usage: branch [options]\n"
"Options are :\n"
" : list local branches."
" -r: list remote branches.\n"
" -d <branch_name>: delete local branch.\n");
exit(1);
}

static void parse_options(const char **repo_path, branch_options *opts, struct args_info *args)
{
memset(opts, 0, sizeof(*opts));

/* Default values */
opts->list = 1;
opts->remote = 0;
opts->delete = 0;
opts->branch_name = NULL;

for (args->pos = 1; args->pos < args->argc; ++args->pos) {
const char *curr = args->argv[args->pos];

if (match_arg_separator(args)) {
break;
} else if (!strcmp(curr, "-r")) {
opts->remote = 1;
if (args->pos != args->argc -1) {
print_usage();
}
} else if (!strcmp(curr, "-d")) {
opts->list = 0;
opts->delete = 1;

if (args->pos == args->argc -1) {
print_usage();
} else {
opts->branch_name = strdup(args->argv[args->pos + 1]);
}
}
}
}

int lg2_branch(git_repository *repo, int argc, char **argv)
{
struct args_info args = ARGS_INFO_INIT;
branch_options opts;
const char *path = ".";

git_branch_iterator *iter = NULL;
git_branch_t git_branch_type = GIT_BRANCH_LOCAL;
git_reference *ref = NULL;
git_reference *upstream_ref = NULL;

/** Parse our command line options */
parse_options(&path, &opts, &args);

if (opts.list) {
if (opts.remote) {
git_branch_type = GIT_BRANCH_REMOTE;
}

// Create the branch iterator for branches
if (git_branch_iterator_new(&iter, repo, git_branch_type) != 0) {
fprintf(stderr, "Could not create branch iterator\n");
goto cleanup;
}

// Iterate through the branches
while (git_branch_next(&ref, &git_branch_type, iter) != GIT_ITEROVER) {
const char *branch_name;
if (git_branch_name(&branch_name, ref) == 0) {
if (!opts.remote) {
if (git_branch_upstream(&upstream_ref, ref) == 0) {
printf("%s:%s\n", branch_name, branch_name);
} else {
printf("%s\n", branch_name);
}
} else {
printf("%s\n", branch_name);
}

}
git_reference_free(ref);
}
} else if (opts.delete) {
// Lookup the reference for the branch
if (git_branch_lookup(&ref, repo, opts.branch_name, GIT_BRANCH_LOCAL) != 0) {
fprintf(stderr, "Error looking up branch: %s\n", opts.branch_name);
goto cleanup;
}

// Delete the reference
if (git_branch_delete(ref) != 0) {
fprintf(stderr, "Error deleting branch: %s\n", opts.branch_name);
goto cleanup;
}
}

cleanup:
if (iter) git_branch_iterator_free(iter);

return 0;
}
2 changes: 0 additions & 2 deletions libgit2patchedfiles/examples/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,6 @@ int lg2_checkout(git_repository *repo, int argc, char **argv)

err = git_branch_set_upstream(branch_ref,upstreamname);
if (err == GIT_ENOTFOUND) {
// no upstream exists
git_error_clear();
err = 0;
}
if (err != 0) {
Expand Down
5 changes: 5 additions & 0 deletions libgit2patchedfiles/examples/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

extern int lg2_add(git_repository *repo, int argc, char **argv);
extern int lg2_blame(git_repository *repo, int argc, char **argv);
extern int lg2_branch(git_repository *repo, int argc, char **argv);
extern int lg2_cat_file(git_repository *repo, int argc, char **argv);
extern int lg2_checkout(git_repository *repo, int argc, char **argv);
extern int lg2_clone(git_repository *repo, int argc, char **argv);
Expand All @@ -69,10 +70,14 @@ extern int lg2_general(git_repository *repo, int argc, char **argv);
extern int lg2_index_pack(git_repository *repo, int argc, char **argv);
extern int lg2_init(git_repository *repo, int argc, char **argv);
extern int lg2_log(git_repository *repo, int argc, char **argv);
extern int lg2_log_last_commit_of_branch(git_repository *repo, int argc, char **argv);
extern int lg2_log_git_merge_base(git_repository *repo, int argc, char **argv);
extern int lg2_log_git_merge_base_commits(git_repository *repo, int argc, char **argv);
extern int lg2_ls_files(git_repository *repo, int argc, char **argv);
extern int lg2_ls_remote(git_repository *repo, int argc, char **argv);
extern int lg2_merge(git_repository *repo, int argc, char **argv);
extern int lg2_push(git_repository *repo, int argc, char **argv);
extern int lg2_rebase(git_repository *repo, int argc, char **argv);
extern int lg2_remote(git_repository *repo, int argc, char **argv);
extern int lg2_reset(git_repository *repo, int argc, char **argv);
extern int lg2_revert(git_repository *repo, int argc, char **argv);
Expand Down
Loading
Loading