/*
- * Copyright (C) 2012 the libgit2 contributors
+ * Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
#include "common.h"
#include "git2/config.h"
+#include "git2/sys/config.h"
#include "git2/types.h"
#include "git2/repository.h"
#include "git2/index.h"
#include "git2/submodule.h"
#include "buffer.h"
+#include "buf_text.h"
#include "vector.h"
#include "posix.h"
#include "config_file.h"
str, static kh_inline, const char *, void *, 1,
str_hash_no_trailing_slash, str_equal_no_trailing_slash);
-static int load_submodule_config(git_repository *repo, bool force);
-static git_config_file *open_gitmodules(git_repository *, bool, const git_oid *);
+static int load_submodule_config(git_repository *repo);
+static git_config_backend *open_gitmodules(git_repository *, bool, const git_oid *);
static int lookup_head_remote(git_buf *url, git_repository *repo);
static int submodule_get(git_submodule **, git_repository *, const char *, const char *);
static void submodule_release(git_submodule *sm, int decr);
assert(repo && name);
- if ((error = load_submodule_config(repo, false)) < 0)
+ if ((error = load_submodule_config(repo)) < 0)
return error;
pos = git_strmap_lookup_index(repo->submodules, name);
assert(repo && callback);
- if ((error = load_submodule_config(repo, false)) < 0)
+ if ((error = load_submodule_config(repo)) < 0)
return error;
git_strmap_foreach_value(repo->submodules, sm, {
* and path are not the same.
*/
if (sm->refcount > 1) {
- if (git_vector_bsearch(&seen, sm) != GIT_ENOTFOUND)
+ if (git_vector_bsearch(NULL, &seen, sm) != GIT_ENOTFOUND)
continue;
if ((error = git_vector_insert(&seen, sm)) < 0)
break;
int use_gitlink)
{
int error = 0;
- git_config_file *mods = NULL;
+ git_config_backend *mods = NULL;
git_submodule *sm;
git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
- git_repository_init_options initopt;
+ git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
git_repository *subrepo = NULL;
assert(repo && url && path);
* Old style: sub-repo goes directly into repo/<name>/.git/
*/
- memset(&initopt, 0, sizeof(initopt));
initopt.flags = GIT_REPOSITORY_INIT_MKPATH |
GIT_REPOSITORY_INIT_NO_REINIT;
initopt.origin_url = real_url.ptr;
assert(sm);
if ((error = git_repository_index__weakptr(&index, sm->owner)) < 0 ||
- (error = git_index_add_from_workdir(index, GIT_MODULES_FILE)) < 0)
+ (error = git_index_add_bypath(index, GIT_MODULES_FILE)) < 0)
return error;
return git_submodule_add_to_index(sm, true);
int git_submodule_add_to_index(git_submodule *sm, int write_index)
{
int error;
- git_repository *repo, *sm_repo;
+ git_repository *repo, *sm_repo = NULL;
git_index *index;
git_buf path = GIT_BUF_INIT;
git_commit *head;
int git_submodule_save(git_submodule *submodule)
{
int error = 0;
- git_config_file *mods;
+ git_config_backend *mods;
git_buf key = GIT_BUF_INIT;
assert(submodule);
return 0;
}
-const git_oid *git_submodule_index_oid(git_submodule *submodule)
+const git_oid *git_submodule_index_id(git_submodule *submodule)
{
assert(submodule);
return NULL;
}
-const git_oid *git_submodule_head_oid(git_submodule *submodule)
+const git_oid *git_submodule_head_id(git_submodule *submodule)
{
assert(submodule);
return NULL;
}
-const git_oid *git_submodule_wd_oid(git_submodule *submodule)
+const git_oid *git_submodule_wd_id(git_submodule *submodule)
{
assert(submodule);
git_buf_free(&path);
/* if we have opened the submodule successfully, let's grab the HEAD OID */
- if (!error && !(submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)) {
- if (!git_reference_name_to_oid(
+ if (!error) {
+ if (!git_reference_name_to_id(
&submodule->wd_oid, *subrepo, GIT_HEAD_FILE))
submodule->flags |= GIT_SUBMODULE_STATUS__WD_OID_VALID;
else
int git_submodule_reload_all(git_repository *repo)
{
assert(repo);
- return load_submodule_config(repo, true);
+ git_submodule_config_free(repo);
+ return load_submodule_config(repo);
}
int git_submodule_reload(git_submodule *submodule)
{
git_repository *repo;
git_index *index;
- int pos, error;
+ int error;
+ size_t pos;
git_tree *head;
- git_config_file *mods;
+ git_config_backend *mods;
assert(submodule);
~(GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS__INDEX_OID_VALID);
- pos = git_index_find(index, submodule->path);
- if (pos >= 0) {
- git_index_entry *entry = git_index_get_byindex(index, pos);
+ if (!git_index_find(&pos, index, submodule->path)) {
+ const git_index_entry *entry = git_index_get_byindex(index, pos);
if (S_ISGITLINK(entry->mode)) {
if ((error = submodule_load_from_index(repo, entry)) < 0)
git_buf path = GIT_BUF_INIT;
git_buf_sets(&path, "submodule\\.");
- git_buf_puts_escape_regex(&path, submodule->name);
+ git_buf_text_puts_escape_regex(&path, submodule->name);
git_buf_puts(&path, ".*");
if (git_buf_oom(&path))
return error;
}
+int git_submodule_location(
+ unsigned int *location_status,
+ git_submodule *submodule)
+{
+ assert(location_status && submodule);
+
+ *location_status = submodule->flags &
+ (GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX |
+ GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_IN_WD);
+
+ return 0;
+}
+
+
/*
* INTERNAL FUNCTIONS
*/
git_repository *repo, git_oid *gitmodules_oid)
{
int error;
+ git_index *index;
git_iterator *i;
const git_index_entry *entry;
- if ((error = git_iterator_for_repo_index(&i, repo)) < 0)
+ if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
+ (error = git_iterator_for_index(&i, index, 0, NULL, NULL)) < 0)
return error;
- error = git_iterator_current(i, &entry);
+ error = git_iterator_current(&entry, i);
while (!error && entry != NULL) {
git_oid_cpy(gitmodules_oid, &entry->oid);
}
- error = git_iterator_advance(i, &entry);
+ error = git_iterator_advance(&entry, i);
}
git_iterator_free(i);
if ((error = git_repository_head_tree(&head, repo)) < 0)
return error;
- if ((error = git_iterator_for_tree(&i, repo, head)) < 0) {
+ if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0) {
git_tree_free(head);
return error;
}
- error = git_iterator_current(i, &entry);
+ error = git_iterator_current(&entry, i);
while (!error && entry != NULL) {
git_oid_cpy(gitmodules_oid, &entry->oid);
}
- error = git_iterator_advance(i, &entry);
+ error = git_iterator_advance(&entry, i);
}
git_iterator_free(i);
return error;
}
-static git_config_file *open_gitmodules(
+static git_config_backend *open_gitmodules(
git_repository *repo,
bool okay_to_create,
const git_oid *gitmodules_oid)
{
const char *workdir = git_repository_workdir(repo);
git_buf path = GIT_BUF_INIT;
- git_config_file *mods = NULL;
+ git_config_backend *mods = NULL;
if (workdir != NULL) {
if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0)
return mods;
}
-static int load_submodule_config(git_repository *repo, bool force)
+static int load_submodule_config(git_repository *repo)
{
int error;
git_oid gitmodules_oid;
git_buf path = GIT_BUF_INIT;
- git_config_file *mods = NULL;
+ git_config_backend *mods = NULL;
- if (repo->submodules && !force)
+ if (repo->submodules)
return 0;
memset(&gitmodules_oid, 0, sizeof(gitmodules_oid));
goto cleanup;
}
- if ((error = git_branch_tracking(&remote, head)) < 0)
+ if ((error = git_branch_upstream(&remote, head)) < 0)
goto cleanup;
/* remote should refer to something like refs/remotes/ORIGIN/BRANCH */
if (git_reference_type(remote) != GIT_REF_SYMBOLIC ||
- git__prefixcmp(git_reference_target(remote), GIT_REFS_REMOTES_DIR) != 0)
+ git__prefixcmp(git_reference_symbolic_target(remote), GIT_REFS_REMOTES_DIR) != 0)
{
giterr_set(GITERR_SUBMODULE,
"Cannot resolve relative URL when HEAD is not symbolic");
goto cleanup;
}
- scan = tgt = git_reference_target(remote) + strlen(GIT_REFS_REMOTES_DIR);
+ scan = tgt = git_reference_symbolic_target(remote) + strlen(GIT_REFS_REMOTES_DIR);
while (*scan && (*scan != '/' || (scan > tgt && scan[-1] != '\\')))
scan++; /* find non-escaped slash to end ORIGIN name */
goto cleanup;
if (!value)
- error = git_config_delete(config, key.ptr);
+ error = git_config_delete_entry(config, key.ptr);
else
error = git_config_set_string(config, key.ptr, value);
static int submodule_index_status(unsigned int *status, git_submodule *sm)
{
- const git_oid *head_oid = git_submodule_head_oid(sm);
- const git_oid *index_oid = git_submodule_index_oid(sm);
+ const git_oid *head_oid = git_submodule_head_id(sm);
+ const git_oid *index_oid = git_submodule_index_id(sm);
if (!head_oid) {
if (index_oid)
const git_oid *wd_oid, *index_oid;
git_repository *sm_repo = NULL;
- /* open repo now if we need it (so wd_oid() call won't reopen) */
+ /* open repo now if we need it (so wd_id() call won't reopen) */
if ((sm->ignore == GIT_SUBMODULE_IGNORE_NONE ||
sm->ignore == GIT_SUBMODULE_IGNORE_UNTRACKED) &&
(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) != 0)
return error;
}
- index_oid = git_submodule_index_oid(sm);
- wd_oid = git_submodule_wd_oid(sm);
+ index_oid = git_submodule_index_id(sm);
+ wd_oid = git_submodule_wd_id(sm);
if (!index_oid) {
if (wd_oid)
if (sm_repo != NULL) {
git_tree *sm_head;
- git_diff_options opt;
+ git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
/* the diffs below could be optimized with an early termination
if ((error = git_repository_head_tree(&sm_head, sm_repo)) < 0)
return error;
- memset(&opt, 0, sizeof(opt));
if (sm->ignore == GIT_SUBMODULE_IGNORE_NONE)
opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
- error = git_diff_index_to_tree(&diff, sm_repo, sm_head, NULL, &opt);
+ error = git_diff_tree_to_index(&diff, sm_repo, sm_head, NULL, &opt);
if (!error) {
if (git_diff_num_deltas(diff) > 0)
/* perform index-to-workdir diff on submodule */
- error = git_diff_workdir_to_index(&diff, sm_repo, NULL, &opt);
+ error = git_diff_index_to_workdir(&diff, sm_repo, NULL, &opt);
if (!error) {
size_t untracked =
if (untracked > 0)
*status |= GIT_SUBMODULE_STATUS_WD_UNTRACKED;
- if ((git_diff_num_deltas(diff) - untracked) > 0)
+ if (git_diff_num_deltas(diff) != untracked)
*status |= GIT_SUBMODULE_STATUS_WD_WD_MODIFIED;
git_diff_list_free(diff);