diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-23 15:40:01 +1200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2015-02-15 06:03:19 -0800 |
commit | e287590e4b70cbe9ee6e80bbaf81feb79e464dac (patch) | |
tree | bca89f7eecdba97f7353c841b17fd72cf6866916 /git-access.c | |
parent | 4a146f9e57bf63c3555ebc048acc2012229fe08a (diff) | |
download | subsurface-e287590e4b70cbe9ee6e80bbaf81feb79e464dac.tar.gz |
Start splitting out git repo helper routines
This doesn't actually change any code, but it moves the 'is_git_repo()'
function that is used by both loading and saving into a new git-access.c
file.
This is where I'll start doing remote repo syncing too. Knock wood.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'git-access.c')
-rw-r--r-- | git-access.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/git-access.c b/git-access.c new file mode 100644 index 000000000..3b01623b9 --- /dev/null +++ b/git-access.c @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <git2.h> + +#include "dive.h" + +/* + * If it's not a git repo, return NULL. Be very conservative. + */ +struct git_repository *is_git_repository(const char *filename, const char **branchp) +{ + int flen, blen, ret; + struct stat st; + git_repository *repo; + char *loc, *branch; + + flen = strlen(filename); + if (!flen || filename[--flen] != ']') + return NULL; + + /* Find the matching '[' */ + blen = 0; + while (flen && filename[--flen] != '[') + blen++; + + if (!flen) + return NULL; + + /* + * This is the "point of no return": the name matches + * the git repository name rules, and we will no longer + * return NULL. + * + * We will either return "dummy_git_repository" and the + * branch pointer will have the _whole_ filename in it, + * or we will return a real git repository with the + * branch pointer being filled in with just the branch + * name. + * + * The actual git reading/writing routines can use this + * to generate proper error messages. + */ + *branchp = filename; + loc = malloc(flen+1); + if (!loc) + return dummy_git_repository; + memcpy(loc, filename, flen); + loc[flen] = 0; + + branch = malloc(blen+1); + if (!branch) { + free(loc); + return dummy_git_repository; + } + memcpy(branch, filename+flen+1, blen); + branch[blen] = 0; + + if (stat(loc, &st) < 0 || !S_ISDIR(st.st_mode)) { + free(loc); + free(branch); + return dummy_git_repository; + } + + ret = git_repository_open(&repo, loc); + free(loc); + if (ret < 0) { + free(branch); + return dummy_git_repository; + } + *branchp = branch; + return repo; +} |