summaryrefslogtreecommitdiff
path: root/src/tmp_repo.c
diff options
context:
space:
mode:
authorAargh Rai <aargh.rai+git@gmail.com>2026-10-20 11:20:15 +0530
committerAargh Rai <aargh.rai+git@gmail.com>2026-10-20 11:20:15 +0530
commit0f3997d6ff2d25c0941824ec3daa3c8e767bd73e (patch)
treed6110910cfa976b5bfd57139e3810d2924bbba9e /src/tmp_repo.c
parent790131205281884585d4418ae7093636d6e61c97 (diff)
wrote the entire thing using libgit2
Diffstat (limited to 'src/tmp_repo.c')
-rw-r--r--src/tmp_repo.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/tmp_repo.c b/src/tmp_repo.c
new file mode 100644
index 0000000..ff4536c
--- /dev/null
+++ b/src/tmp_repo.c
@@ -0,0 +1,72 @@
+#include <unistd.h>
+#include <sys/random.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <string.h>
+
+#include "lib.h"
+
+struct tmp_repo tmp_repo_init() {
+ unsigned char rng_bytes[64];
+ assert(getrandom(rng_bytes, sizeof(rng_bytes), 0) == sizeof(rng_bytes));
+
+ char repo_path[70] = "/tmp/";
+ for (int i = 0; i < 64; i++) {
+ repo_path[5 + i] = (char)('a' + rng_bytes[i] % 26);
+ }
+ repo_path[69] = '\0';
+
+ git_libgit2_init();
+
+ git_repository *repo = NULL;
+ assert(git_repository_init(&repo, repo_path, 0) == 0);
+ struct tmp_repo output;
+ memcpy(output.path, repo_path, 70);
+ output.repo = repo;
+ return output;
+}
+
+void tmp_repo_deinit(struct tmp_repo repo) {
+ pid_t pid;
+ if ((pid = fork()) == 0) {
+ char *argv[] = {"/usr/bin/rm", "-rf", repo.path, NULL};
+ execv(argv[0], argv);
+ }
+ assert(waitpid(pid, NULL, 0) != -1);
+}
+
+int check_for_backupignore() {
+ FILE *file = fopen(".backupignore", "r");
+ if (file == NULL) {
+ fprintf(stderr, "Missing .backupignore file in the current directory\n");
+ return 1;
+ } else fclose(file);
+ return 0;
+}
+
+void copy_over_backupignore(struct tmp_repo repo) {
+ char cp_destination[81];
+ snprintf(cp_destination, 81, "%s/.gitignore", repo.path);
+
+ pid_t pid;
+ if ((pid = fork()) == 0) {
+ char *argv[] = {"/usr/bin/cp", ".backupignore", cp_destination, NULL};
+ execv(argv[0], argv);
+ }
+ assert(waitpid(pid, NULL, 0) != -1);
+}
+
+int is_ignored(struct tmp_repo repo, char *path) {
+ if (is_git_metadata_dir(path)) return 0;
+ int ignored;
+ assert(git_ignore_path_is_ignored(&ignored, repo.repo, path) >= 0);
+ return ignored;
+}
+
+int is_git_metadata_dir(char *path) {
+ int n = strnlen(path, PATH_MAX);
+ for (int i = 0; i < n - 6; i++) {
+ if (strncmp(path + i, "/.git/", 6) == 0) return 1;
+ }
+ return 0;
+}