summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c26
-rw-r--r--src/config.h13
-rw-r--r--src/pack-objects.h10
-rw-r--r--src/reflog.c41
-rw-r--r--src/repository.c74
-rw-r--r--src/revparse.c6
-rw-r--r--src/stash.c4
-rw-r--r--src/tag.c2
8 files changed, 120 insertions, 56 deletions
diff --git a/src/config.c b/src/config.c
index 01a54ecf2..412965b73 100644
--- a/src/config.c
+++ b/src/config.c
@@ -90,6 +90,13 @@ int git_config_add_file_ondisk(
git_config_file *file = NULL;
int res;
+ assert(cfg && path);
+
+ if (!git_path_isfile(path)) {
+ giterr_set(GITERR_CONFIG, "File '%s' doesn't exists.", path);
+ return GIT_ENOTFOUND;
+ }
+
if (git_config_file__ondisk(&file, path) < 0)
return -1;
@@ -105,17 +112,22 @@ int git_config_add_file_ondisk(
return 0;
}
-int git_config_open_ondisk(git_config **cfg, const char *path)
+int git_config_open_ondisk(git_config **out, const char *path)
{
- if (git_config_new(cfg) < 0)
- return -1;
+ int error;
+ git_config *config;
- if (git_config_add_file_ondisk(*cfg, path, GIT_CONFIG_LEVEL_LOCAL, 0) < 0) {
- git_config_free(*cfg);
+ *out = NULL;
+
+ if (git_config_new(&config) < 0)
return -1;
- }
- return 0;
+ if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0)
+ git_config_free(config);
+ else
+ *out = config;
+
+ return error;
}
static int find_internal_file_by_level(
diff --git a/src/config.h b/src/config.h
index a0569ec93..c7595ee79 100644
--- a/src/config.h
+++ b/src/config.h
@@ -32,4 +32,17 @@ extern int git_config_rename_section(
const char *old_section_name, /* eg "branch.dummy" */
const char *new_section_name); /* NULL to drop the old section */
+/**
+ * Create a configuration file backend for ondisk files
+ *
+ * These are the normal `.gitconfig` files that Core Git
+ * processes. Note that you first have to add this file to a
+ * configuration object before you can query it for configuration
+ * variables.
+ *
+ * @param out the new backend
+ * @param path where the config file is located
+ */
+extern int git_config_file__ondisk(struct git_config_file **out, const char *path);
+
#endif
diff --git a/src/pack-objects.h b/src/pack-objects.h
index 8c01f7189..e34cc2754 100644
--- a/src/pack-objects.h
+++ b/src/pack-objects.h
@@ -71,11 +71,11 @@ struct git_packbuilder {
git_cond progress_cond;
/* configs */
- unsigned long delta_cache_size;
- unsigned long max_delta_cache_size;
- unsigned long cache_max_small_delta_size;
- unsigned long big_file_threshold;
- unsigned long window_memory_limit;
+ uint64_t delta_cache_size;
+ uint64_t max_delta_cache_size;
+ uint64_t cache_max_small_delta_size;
+ uint64_t big_file_threshold;
+ uint64_t window_memory_limit;
int nr_threads; /* nr of threads to use */
diff --git a/src/reflog.c b/src/reflog.c
index 0e333aa6f..7b07c6a9f 100644
--- a/src/reflog.c
+++ b/src/reflog.c
@@ -291,8 +291,8 @@ success:
int git_reflog_append(git_reflog *reflog, const git_oid *new_oid,
const git_signature *committer, const char *msg)
{
- int count;
git_reflog_entry *entry;
+ const git_reflog_entry *previous;
const char *newline;
assert(reflog && new_oid && committer);
@@ -319,16 +319,12 @@ int git_reflog_append(git_reflog *reflog, const git_oid *new_oid,
}
}
- count = git_reflog_entrycount(reflog);
+ previous = git_reflog_entry_byindex(reflog, 0);
- if (count == 0)
+ if (previous == NULL)
git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO);
- else {
- const git_reflog_entry *previous;
-
- previous = git_reflog_entry_byindex(reflog, count -1);
+ else
git_oid_cpy(&entry->oid_old, &previous->oid_cur);
- }
git_oid_cpy(&entry->oid_cur, new_oid);
@@ -417,8 +413,16 @@ unsigned int git_reflog_entrycount(git_reflog *reflog)
const git_reflog_entry * git_reflog_entry_byindex(git_reflog *reflog, size_t idx)
{
+ int pos;
+
assert(reflog);
- return git_vector_get(&reflog->entries, idx);
+
+ pos = git_reflog_entrycount(reflog) - (idx + 1);
+
+ if (pos < 0)
+ return NULL;
+
+ return git_vector_get(&reflog->entries, pos);
}
const git_oid * git_reflog_entry_oidold(const git_reflog_entry *entry)
@@ -447,7 +451,7 @@ char * git_reflog_entry_msg(const git_reflog_entry *entry)
int git_reflog_drop(
git_reflog *reflog,
- unsigned int idx,
+ size_t idx,
int rewrite_previous_entry)
{
unsigned int entrycount;
@@ -457,30 +461,31 @@ int git_reflog_drop(
entrycount = git_reflog_entrycount(reflog);
- if (idx >= entrycount)
+ entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
+
+ if (entry == NULL)
return GIT_ENOTFOUND;
- entry = git_vector_get(&reflog->entries, idx);
reflog_entry_free(entry);
- if (git_vector_remove(&reflog->entries, idx) < 0)
+ if (git_vector_remove(&reflog->entries, entrycount - (idx + 1)) < 0)
return -1;
if (!rewrite_previous_entry)
return 0;
/* No need to rewrite anything when removing the most recent entry */
- if (idx == entrycount - 1)
+ if (idx == 0)
return 0;
- /* There are no more entries in the log */
+ /* Have the latest entry just been dropped? */
if (entrycount == 1)
return 0;
- entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
+ entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx - 1);
/* If the oldest entry has just been removed... */
- if (idx == 0) {
+ if (idx == entrycount - 1) {
/* ...clear the oid_old member of the "new" oldest entry */
if (git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO) < 0)
return -1;
@@ -488,7 +493,7 @@ int git_reflog_drop(
return 0;
}
- previous = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx - 1);
+ previous = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
git_oid_cpy(&entry->oid_old, &previous->oid_cur);
return 0;
diff --git a/src/repository.c b/src/repository.c
index 101497c4d..c1756b1bc 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -750,6 +750,23 @@ static bool are_symlinks_supported(const char *wd_path)
return _symlinks_supported;
}
+static int create_empty_file(const char *path, mode_t mode)
+{
+ int fd;
+
+ if ((fd = p_creat(path, mode)) < 0) {
+ giterr_set(GITERR_OS, "Error while creating '%s'", path);
+ return -1;
+ }
+
+ if (p_close(fd) < 0) {
+ giterr_set(GITERR_OS, "Error while closing '%s'", path);
+ return -1;
+ }
+
+ return 0;
+}
+
static int repo_init_config(
const char *repo_dir,
const char *work_dir,
@@ -766,6 +783,12 @@ static int repo_init_config(
if (git_buf_joinpath(&cfg_path, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
return -1;
+ if (!git_path_isfile(git_buf_cstr(&cfg_path)) &&
+ create_empty_file(git_buf_cstr(&cfg_path), GIT_CONFIG_FILE_MODE) < 0) {
+ git_buf_free(&cfg_path);
+ return -1;
+ }
+
if (git_config_open_ondisk(&config, git_buf_cstr(&cfg_path)) < 0) {
git_buf_free(&cfg_path);
return -1;
@@ -1241,36 +1264,47 @@ int git_repository_head_orphan(git_repository *repo)
return 0;
}
-int git_repository_is_empty(git_repository *repo)
+int at_least_one_cb(const char *refname, void *payload)
{
- git_reference *head = NULL, *branch = NULL;
- int error;
+ GIT_UNUSED(refname);
+ GIT_UNUSED(payload);
- if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
- return -1;
+ return GIT_EUSER;
+}
- if (git_reference_type(head) != GIT_REF_SYMBOLIC) {
- git_reference_free(head);
- return 0;
- }
+static int repo_contains_no_reference(git_repository *repo)
+{
+ int error;
+
+ error = git_reference_foreach(repo, GIT_REF_LISTALL, at_least_one_cb, NULL);
- if (strcmp(git_reference_target(head), GIT_REFS_HEADS_DIR "master") != 0) {
- git_reference_free(head);
+ if (error == GIT_EUSER)
return 0;
- }
-
- error = git_reference_resolve(&branch, head);
- git_reference_free(head);
- git_reference_free(branch);
+ return error == 0 ? 1 : error;
+}
- if (error == GIT_ENOTFOUND)
- return 1;
+int git_repository_is_empty(git_repository *repo)
+{
+ git_reference *head = NULL;
+ int error, ref_count = 0;
- if (error < 0)
+ if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
return -1;
- return 0;
+ if (!(error = git_reference_type(head) == GIT_REF_SYMBOLIC))
+ goto cleanup;
+
+ if (!(error = strcmp(
+ git_reference_target(head),
+ GIT_REFS_HEADS_DIR "master") == 0))
+ goto cleanup;
+
+ error = repo_contains_no_reference(repo);
+
+cleanup:
+ git_reference_free(head);
+ return error < 0 ? -1 : error;
}
const char *git_repository_path(git_repository *repo)
diff --git a/src/revparse.c b/src/revparse.c
index 83eea7d3f..6a7587d6a 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -201,7 +201,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out,
numentries = git_reflog_entrycount(reflog);
- for (i = numentries - 1; i >= 0; i--) {
+ for (i = 0; i < numentries; i++) {
entry = git_reflog_entry_byindex(reflog, i);
msg = git_reflog_entry_msg(entry);
@@ -263,7 +263,7 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, unsigned i
}
entry = git_reflog_entry_byindex(reflog, identifier);
- git_oid_cpy(oid, git_reflog_entry_oidold(entry));
+ git_oid_cpy(oid, git_reflog_entry_oidnew(entry));
error = 0;
goto cleanup;
@@ -271,7 +271,7 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, unsigned i
int i;
git_time commit_time;
- for (i = numentries - 1; i >= 0; i--) {
+ for (i = 0; i < numentries; i++) {
entry = git_reflog_entry_byindex(reflog, i);
commit_time = git_reflog_entry_committer(entry)->when;
diff --git a/src/stash.c b/src/stash.c
index 627d271f4..b74429aca 100644
--- a/src/stash.c
+++ b/src/stash.c
@@ -600,7 +600,7 @@ int git_stash_foreach(
max = git_reflog_entrycount(reflog);
for (i = 0; i < max; i++) {
- entry = git_reflog_entry_byindex(reflog, max - i - 1);
+ entry = git_reflog_entry_byindex(reflog, i);
if (callback(i,
git_reflog_entry_msg(entry),
@@ -642,7 +642,7 @@ int git_stash_drop(
goto cleanup;
}
- if ((error = git_reflog_drop(reflog, max - index - 1, true)) < 0)
+ if ((error = git_reflog_drop(reflog, index, true)) < 0)
goto cleanup;
if ((error = git_reflog_write(reflog)) < 0)
diff --git a/src/tag.c b/src/tag.c
index 4c3d811eb..13369d9fb 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -39,7 +39,7 @@ const git_oid *git_tag_target_oid(git_tag *t)
return &t->target;
}
-git_otype git_tag_type(git_tag *t)
+git_otype git_tag_target_type(git_tag *t)
{
assert(t);
return t->type;