static int check_object_files(object_data *d) { if (gitfo_exists(d->dir) < 0) return -1; if (gitfo_exists(d->file) < 0) return -1; return 0; }
static int repo_init_check_head_existence(char * repository_path) { char temp_path[GIT_PATH_MAX]; git__joinpath(temp_path, repository_path, GIT_HEAD_FILE); return gitfo_exists(temp_path); }
static int index_initialize(git_index **index_out, git_repository *owner, const char *index_path) { git_index *index; assert(index_out && index_path); index = git__malloc(sizeof(git_index)); if (index == NULL) return GIT_ENOMEM; memset(index, 0x0, sizeof(git_index)); index->index_file_path = git__strdup(index_path); if (index->index_file_path == NULL) { free(index); return GIT_ENOMEM; } index->repository = owner; /* Check if index file is stored on disk already */ if (gitfo_exists(index->index_file_path) == 0) index->on_disk = 1; *index_out = index; return GIT_SUCCESS; }
static int scan_one_pack(void *state, char *name) { struct scanned_pack **ret = state, *r; char *s = strrchr(name, '/'), *d; if (git__prefixcmp(s + 1, "pack-") || git__suffixcmp(s, ".pack") || strlen(s + 1) != GIT_PACK_NAME_MAX + 4) return 0; d = strrchr(s + 1, '.'); strcpy(d + 1, "idx"); /* "pack-abc.pack" -> "pack-abc.idx" */ if (gitfo_exists(name)) return 0; if ((r = git__malloc(sizeof(*r))) == NULL) return GIT_ERROR; *d = '\0'; /* "pack-abc.pack" -_> "pack-abc" */ if ((r->pack = alloc_pack(s + 1)) == NULL) { free(r); return GIT_ERROR; } r->next = *ret; *ret = r; return 0; }
static int load_alternates(git_odb *odb, const char *objects_dir) { char alternates_path[GIT_PATH_MAX]; char alternate[GIT_PATH_MAX]; char *buffer; gitfo_buf alternates_buf = GITFO_BUF_INIT; int error; git__joinpath(alternates_path, objects_dir, GIT_ALTERNATES_FILE); if (gitfo_exists(alternates_path) < GIT_SUCCESS) return GIT_SUCCESS; if (gitfo_read_file(&alternates_buf, alternates_path) < GIT_SUCCESS) return GIT_EOSERR; buffer = (char *)alternates_buf.data; error = GIT_SUCCESS; /* add each alternate as a new backend; one alternate per line */ while ((error == GIT_SUCCESS) && (buffer = git__strtok(alternate, buffer, "\r\n")) != NULL) error = add_default_backends(odb, alternate, 1); gitfo_free_buf(&alternates_buf); return error; }
/* * Git repository open methods * * Open a repository object from its path */ static int assign_repository_DIRs(git_repository *repo, const char *git_dir, const char *git_object_directory, const char *git_index_file, const char *git_work_tree) { char path_aux[GIT_PATH_MAX]; size_t path_len; assert(repo); if (git_dir == NULL || gitfo_isdir(git_dir) < GIT_SUCCESS) return GIT_ENOTFOUND; /* store GIT_DIR */ path_len = strlen(git_dir); strcpy(path_aux, git_dir); if (path_aux[path_len - 1] != '/') { path_aux[path_len] = '/'; path_aux[path_len + 1] = 0; path_len = path_len + 1; } repo->path_repository = git__strdup(path_aux); /* store GIT_OBJECT_DIRECTORY */ if (git_object_directory == NULL) strcpy(path_aux + path_len, GIT_OBJECTS_DIR); else strcpy(path_aux, git_object_directory); if (gitfo_isdir(path_aux) < GIT_SUCCESS) return GIT_ENOTFOUND; repo->path_odb = git__strdup(path_aux); /* store GIT_INDEX_FILE */ if (git_index_file == NULL) strcpy(path_aux + path_len, GIT_INDEX_FILE); else strcpy(path_aux, git_index_file); if (gitfo_exists(path_aux) < 0) return GIT_ENOTFOUND; repo->path_index = git__strdup(path_aux); /* store GIT_WORK_TREE */ if (git_work_tree == NULL) repo->is_bare = 1; else repo->path_workdir = git__strdup(git_work_tree); return GIT_SUCCESS; }
static int guess_repository_DIRs(git_repository *repo, const char *repository_path) { char path_aux[GIT_PATH_MAX], *last_DIR; int path_len; if (gitfo_isdir(repository_path) < GIT_SUCCESS) return GIT_ENOTAREPO; path_len = strlen(repository_path); strcpy(path_aux, repository_path); if (path_aux[path_len - 1] != '/') { path_aux[path_len] = '/'; path_aux[path_len + 1] = 0; path_len = path_len + 1; } repo->path_repository = git__strdup(path_aux); /* objects database */ strcpy(path_aux + path_len, GIT_OBJECTS_DIR); if (gitfo_isdir(path_aux) < GIT_SUCCESS) return GIT_ENOTAREPO; repo->path_odb = git__strdup(path_aux); /* HEAD file */ strcpy(path_aux + path_len, GIT_HEAD_FILE); if (gitfo_exists(path_aux) < 0) return GIT_ENOTAREPO; path_aux[path_len] = 0; last_DIR = (path_aux + path_len - 2); while (*last_DIR != '/') last_DIR--; if (strcmp(last_DIR, GIT_DIR) == 0) { repo->is_bare = 0; /* index file */ strcpy(path_aux + path_len, GIT_INDEX_FILE); repo->path_index = git__strdup(path_aux); /* working dir */ *(last_DIR + 1) = 0; repo->path_workdir = git__strdup(path_aux); } else { repo->is_bare = 1; repo->path_workdir = NULL; } return GIT_SUCCESS; }
static int parse_repository_folders(git_repository *repo, const char *repository_path) { char path_aux[GIT_PATH_MAX], *last_folder; int path_len; if (gitfo_isdir(repository_path) < 0) return GIT_ENOTAREPO; path_len = strlen(repository_path); strcpy(path_aux, repository_path); if (path_aux[path_len - 1] != '/') { path_aux[path_len] = '/'; path_aux[path_len + 1] = 0; path_len = path_len + 1; } repo->path_repository = git__strdup(path_aux); /* objects database */ strcpy(path_aux + path_len, "objects/"); if (gitfo_isdir(path_aux) < 0) return GIT_ENOTAREPO; repo->path_odb = git__strdup(path_aux); /* HEAD file */ strcpy(path_aux + path_len, "HEAD"); if (gitfo_exists(path_aux) < 0) return GIT_ENOTAREPO; path_aux[path_len] = 0; last_folder = (path_aux + path_len - 2); while (*last_folder != '/') last_folder--; if (strcmp(last_folder, "/.git/") == 0) { repo->is_bare = 0; /* index file */ strcpy(path_aux + path_len, "index"); repo->path_index = git__strdup(path_aux); /* working dir */ *(last_folder + 1) = 0; repo->path_workdir = git__strdup(path_aux); } else { repo->is_bare = 1; repo->path_workdir = NULL; } return GIT_SUCCESS; }
static int lock_file(git_filebuf *file, int flags) { if (gitfo_exists(file->path_lock) == 0) { if (flags & GIT_FILEBUF_FORCE) gitfo_unlink(file->path_lock); else return git__throw(GIT_EOSERR, "Failed to lock file"); } /* create path to the file buffer is required */ if (flags & GIT_FILEBUF_FORCE) { file->fd = gitfo_creat_locked_force(file->path_lock, 0644); } else { file->fd = gitfo_creat_locked(file->path_lock, 0644); } if (file->fd < 0) return git__throw(GIT_EOSERR, "Failed to create lock"); if ((flags & GIT_FILEBUF_APPEND) && gitfo_exists(file->path_original) == 0) { git_file source; char buffer[2048]; size_t read_bytes; source = gitfo_open(file->path_original, O_RDONLY); if (source < 0) return git__throw(GIT_EOSERR, "Failed to lock file. Could not open %s", file->path_original); while ((read_bytes = gitfo_read(source, buffer, 2048)) > 0) { gitfo_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } gitfo_close(source); } return GIT_SUCCESS; }
static int lock_file(git_filebuf *file, int flags) { if (gitfo_exists(file->path_lock) == 0) { if (flags & GIT_FILEBUF_FORCE) gitfo_unlink(file->path_lock); else return GIT_EOSERR; } file->fd = gitfo_creat(file->path_lock, 0644); if (file->fd < 0) return GIT_EOSERR; /* TODO: do a flock() in the descriptor file_lock */ if ((flags & GIT_FILEBUF_APPEND) && gitfo_exists(file->path_original) == 0) { git_file source; char buffer[2048]; size_t read_bytes; source = gitfo_open(file->path_original, O_RDONLY); if (source < 0) return GIT_EOSERR; while ((read_bytes = gitfo_read(source, buffer, 2048)) > 0) { gitfo_write(file->fd, buffer, read_bytes); if (file->digest) git_hash_update(file->digest, buffer, read_bytes); } gitfo_close(source); } return GIT_SUCCESS; }
static int repo_init_structure(repo_init *results) { const int mode = 0755; /* or 0777 ? */ char temp_path[GIT_PATH_MAX]; int path_len; char *git_dir = results->path_repository; if (gitfo_mkdir_recurs(git_dir, mode)) return GIT_ERROR; path_len = strlen(git_dir); strcpy(temp_path, git_dir); /* Does HEAD file already exist ? */ strcpy(temp_path + path_len, GIT_HEAD_FILE); if (gitfo_exists(temp_path) == GIT_SUCCESS) return repo_init_reinit(results); if (repo_init_createhead(temp_path) < GIT_SUCCESS) return GIT_ERROR; /* Creates the '/objects/info/' directory */ strcpy(temp_path + path_len, GIT_OBJECTS_INFO_DIR); if (gitfo_mkdir_recurs(temp_path, mode)) return GIT_ERROR; /* Creates the '/objects/pack/' directory */ strcpy(temp_path + path_len, GIT_OBJECTS_PACK_DIR); if (gitfo_mkdir(temp_path, mode)) return GIT_ERROR; /* Creates the '/refs/heads/' directory */ strcpy(temp_path + path_len, GIT_REFS_HEADS_DIR); if (gitfo_mkdir_recurs(temp_path, mode)) return GIT_ERROR; /* Creates the '/refs/tags/' directory */ strcpy(temp_path + path_len, GIT_REFS_TAGS_DIR); if (gitfo_mkdir(temp_path, mode)) return GIT_ERROR; /* TODO: what's left? templates? */ return GIT_SUCCESS; }
static int check_repository_dirs(git_repository *repo) { char path_aux[GIT_PATH_MAX]; if (gitfo_isdir(repo->path_repository) < GIT_SUCCESS) return GIT_ENOTAREPO; /* Ensure GIT_OBJECT_DIRECTORY exists */ if (gitfo_isdir(repo->path_odb) < GIT_SUCCESS) return GIT_ENOTAREPO; /* Ensure HEAD file exists */ git__joinpath(path_aux, repo->path_repository, GIT_HEAD_FILE); if (gitfo_exists(path_aux) < 0) return GIT_ENOTAREPO; return GIT_SUCCESS; }
int git_index_add(git_index *index, const char *rel_path, int stage) { git_index_entry entry; char full_path[GIT_PATH_MAX]; struct stat st; int error; if (index->repository == NULL) return GIT_EBAREINDEX; strcpy(full_path, index->repository->path_workdir); strcat(full_path, rel_path); if (gitfo_exists(full_path) < 0) return GIT_ENOTFOUND; if (gitfo_stat(full_path, &st) < 0) return GIT_EOSERR; if (stage < 0 || stage > 3) return GIT_ERROR; memset(&entry, 0x0, sizeof(git_index_entry)); entry.ctime.seconds = st.st_ctime; entry.mtime.seconds = st.st_mtime; /* entry.mtime.nanoseconds = st.st_mtimensec; */ /* entry.ctime.nanoseconds = st.st_ctimensec; */ entry.dev= st.st_rdev; entry.ino = st.st_ino; entry.mode = st.st_mode; entry.uid = st.st_uid; entry.gid = st.st_gid; entry.file_size = st.st_size; /* write the blob to disk and get the oid */ if ((error = git_blob_writefile(&entry.oid, index->repository, full_path)) < 0) return error; entry.flags |= (stage << GIT_IDXENTRY_STAGESHIFT); entry.path = (char *)rel_path; /* do not duplicate; index_insert already does this */ return git_index_insert(index, &entry); }
void git_filebuf_cleanup(git_filebuf *file) { if (file->fd >= 0) gitfo_close(file->fd); if (file->fd >= 0 && file->path_lock && gitfo_exists(file->path_lock) == GIT_SUCCESS) gitfo_unlink(file->path_lock); if (file->digest) git_hash_free_ctx(file->digest); free(file->buffer); free(file->z_buf); deflateEnd(&file->zs); free(file->path_original); free(file->path_lock); }
void git_filebuf_cleanup(git_filebuf *file) { if (file->fd >= 0) gitfo_close(file->fd); if (gitfo_exists(file->path_lock) == GIT_SUCCESS) gitfo_unlink(file->path_lock); if (file->digest) git_hash_free_ctx(file->digest); free(file->buffer); #ifdef GIT_FILEBUF_THREADS free(file->buffer_back); #endif free(file->path_original); free(file->path_lock); }
int git_index_read(git_index *index) { struct stat indexst; int error = 0; assert(index->index_file_path); if (!index->on_disk || gitfo_exists(index->index_file_path) < 0) { git_index_clear(index); index->on_disk = 0; return 0; } if (gitfo_stat(index->index_file_path, &indexst) < 0) return GIT_EOSERR; if (!S_ISREG(indexst.st_mode)) return GIT_ENOTFOUND; if (indexst.st_mtime != index->last_modified) { gitfo_buf buffer; if (gitfo_read_file(&buffer, index->index_file_path) < 0) return GIT_EOSERR; git_index_clear(index); error = git_index__parse(index, buffer.data, buffer.len); if (error == 0) index->last_modified = indexst.st_mtime; gitfo_free_buf(&buffer); } return error; }
int git_blob_writefile(git_oid *written_id, git_repository *repo, const char *path) { int error; git_blob *blob; if (gitfo_exists(path) < 0) return GIT_ENOTFOUND; if ((error = git_blob_new(&blob, repo)) < GIT_SUCCESS) return error; if ((error = git_blob_set_rawcontent_fromfile(blob, path)) < GIT_SUCCESS) return error; if ((error = git_object_write((git_object *)blob)) < GIT_SUCCESS) return error; git_oid_cpy(written_id, git_object_id((git_object *)blob)); /* FIXME: maybe we don't want to free this already? * the user may want to access it again */ GIT_OBJECT_DECREF(repo, blob); return GIT_SUCCESS; }
/* * Git repository open methods * * Open a repository object from its path */ static int assign_repository_DIRs(git_repository *repo, const char *git_dir, const char *git_object_directory, const char *git_index_file, const char *git_work_tree) { char path_aux[GIT_PATH_MAX]; size_t git_dir_path_len; int error = GIT_SUCCESS; assert(repo); if (git_dir == NULL) return GIT_ENOTFOUND; error = gitfo_prettify_dir_path(path_aux, git_dir); if (error < GIT_SUCCESS) return error; if (gitfo_isdir(path_aux) < GIT_SUCCESS) return GIT_ENOTFOUND; git_dir_path_len = strlen(path_aux); /* store GIT_DIR */ repo->path_repository = git__strdup(path_aux); /* store GIT_OBJECT_DIRECTORY */ if (git_object_directory == NULL) strcpy(repo->path_repository + git_dir_path_len, GIT_OBJECTS_DIR); else { error = gitfo_prettify_dir_path(path_aux, git_object_directory); if (error < GIT_SUCCESS) return error; } if (gitfo_isdir(path_aux) < GIT_SUCCESS) return GIT_ENOTFOUND; repo->path_odb = git__strdup(path_aux); /* store GIT_INDEX_FILE */ if (git_index_file == NULL) strcpy(repo->path_repository + git_dir_path_len, GIT_INDEX_FILE); else { error = gitfo_prettify_file_path(path_aux, git_index_file); if (error < GIT_SUCCESS) return error; } if (gitfo_exists(path_aux) < 0) return GIT_ENOTFOUND; repo->path_index = git__strdup(path_aux); /* store GIT_WORK_TREE */ if (git_work_tree == NULL) repo->is_bare = 1; else { error = gitfo_prettify_dir_path(path_aux, git_work_tree); if (error < GIT_SUCCESS) return error; repo->path_workdir = git__strdup(path_aux); } return GIT_SUCCESS; }