diff options
Diffstat (limited to 'src/GitRepository.cpp')
-rw-r--r-- | src/GitRepository.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/GitRepository.cpp b/src/GitRepository.cpp new file mode 100644 index 0000000..0a3b0a7 --- /dev/null +++ b/src/GitRepository.cpp @@ -0,0 +1,101 @@ +#include "../include/GitRepository.hpp" +#include "../include/Dependency.hpp" +#include <git2.h> +#include <string> +#include <cassert> + +using namespace std; + +static bool libgitInitialized = false; + +namespace sibs +{ + void gitInit() + { + if(!libgitInitialized) + { + libgitInitialized = true; + // TODO: Call git_libgit2_shutdown in destructor? dont really need to do that though + git_libgit2_init(); + } + } + + Result<bool> buildGitError(int error, const string &errorPrefix) + { + const git_error *e = giterr_last(); + string errMsg = errorPrefix; + errMsg += ": "; + errMsg += to_string(error); + errMsg += "/"; + errMsg += to_string(e->klass); + errMsg += ": "; + errMsg += e->message; + return Result<bool>::Err(errMsg, error); + } + + Result<bool> GitRepository::clone(GitDependency *gitDependency, const FileString &repoDirPath) + { + gitInit(); + git_repository *repo; + int error = git_clone(&repo, gitDependency->url.c_str(), toUtf8(repoDirPath).c_str(), NULL); + if(error != 0) + return buildGitError(error, "Failed to clone git repository"); + + git_repository_free(repo); + return Result<bool>::Ok(true); + } + + Result<bool> GitRepository::pull(GitDependency *gitDependency, const FileString &repoDirPath) + { + gitInit(); + int error; + + git_repository *repo; + error = git_repository_open(&repo, toUtf8(repoDirPath).c_str()); + if(error != 0) + return buildGitError(error, "Failed to open git repository"); + + git_remote *remote; + error = git_remote_lookup(&remote, repo, "origin"); + if(error != 0) + return buildGitError(error, "Failed to do remote lookup for git repository"); + + // TODO: Setup option to be able to use callback for progress (for output in console) and handling credentials + error = git_remote_fetch(remote, NULL, NULL, "pull"); + if(error != 0) + { + Result<bool> err = buildGitError(error, "Failed to do remote fetch for git repository"); + git_remote_free(remote); + git_repository_free(repo); + return err; + } + + git_reference *ref; + error = git_reference_dwim(&ref, repo, gitDependency->branch.c_str()); + if(error != 0) + { + Result<bool> err = buildGitError(error, "Failed to do reference lookup for git repository"); + git_remote_free(remote); + git_repository_free(repo); + return err; + } + + git_annotated_commit *annotatedCommit; + error = git_annotated_commit_from_ref(&annotatedCommit, repo, ref); + if(error != 0) + { + Result<bool> err = buildGitError(error, "Failed to get commit from ref"); + git_annotated_commit_free(annotatedCommit); + git_remote_free(remote); + git_repository_free(repo); + return err; + } + + assert(false); + + git_annotated_commit_free(annotatedCommit); + git_remote_free(remote); + git_repository_free(repo); + return Result<bool>::Ok(true); + } +} |