summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoryuangli <yuangli@mathworks.com>2022-08-09 19:24:57 +0100
committeryuangli <yuangli@mathworks.com>2022-08-09 19:24:57 +0100
commitdf5eb3239b1419b3f4382d7bcca9a5d85611d7d3 (patch)
treea5d97cf1c8f6b269bae26f48a6176236e749c005 /src
parent09b3d33d6dba7f4804b478a72dec3258405856c2 (diff)
downloadlibgit2-df5eb3239b1419b3f4382d7bcca9a5d85611d7d3.tar.gz
support fetch unshallow option on shallow repos
Diffstat (limited to 'src')
-rw-r--r--src/libgit2/clone.c7
-rw-r--r--src/libgit2/fetch.c9
-rw-r--r--src/libgit2/repository.c19
-rw-r--r--src/libgit2/transports/smart.c26
4 files changed, 43 insertions, 18 deletions
diff --git a/src/libgit2/clone.c b/src/libgit2/clone.c
index 5e07dc733..6f34cb7ca 100644
--- a/src/libgit2/clone.c
+++ b/src/libgit2/clone.c
@@ -389,11 +389,6 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c
return error;
}
-static int git_fetch_is_shallow(const git_fetch_options *opts)
-{
- return opts->depth > 0;
-}
-
static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch_options *opts, const git_checkout_options *co_opts, const char *branch)
{
int error;
@@ -415,7 +410,7 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch
memcpy(&fetch_opts, opts, sizeof(git_fetch_options));
fetch_opts.update_fetchhead = 0;
- if (!git_fetch_is_shallow(opts))
+ if (opts->depth <= 0)
fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
git_str_printf(&reflog_message, "clone: from %s", git_remote_url(remote));
diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c
index b90ce2ee8..a015cfbd3 100644
--- a/src/libgit2/fetch.c
+++ b/src/libgit2/fetch.c
@@ -61,7 +61,7 @@ static int mark_local(git_remote *remote)
git_vector_foreach(&remote->refs, i, head) {
/* If we have the object, mark it so we don't ask for it */
- if (git_odb_exists(odb, &head->oid))
+ if (remote->nego.depth != INT_MAX && git_odb_exists(odb, &head->oid))
head->local = 1;
else
remote->need_pack = 1;
@@ -173,6 +173,7 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
git_transport *t = remote->transport;
remote->need_pack = 0;
+ remote->nego.depth = opts->unshallow ? INT_MAX : opts->depth;
if (filter_wants(remote, opts) < 0)
return -1;
@@ -181,13 +182,17 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts)
if (!remote->need_pack)
return 0;
+ if (opts->unshallow && opts->depth > 0) {
+ git_error_set(GIT_ERROR_INVALID, "options '--depth' and '--unshallow' cannot be used together");
+ return -1;
+ }
+
/*
* Now we have everything set up so we can start tell the
* server what we want and what we have.
*/
remote->nego.refs = (const git_remote_head * const *)remote->refs.contents;
remote->nego.count = remote->refs.length;
- remote->nego.depth = opts->depth;
remote->nego.shallow_roots = git__malloc(sizeof(git_shallowarray));
git_array_init(remote->nego.shallow_roots->array);
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c
index 0d149a626..13559ef07 100644
--- a/src/libgit2/repository.c
+++ b/src/libgit2/repository.c
@@ -3366,10 +3366,10 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro
assert(repo);
if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0)
- return error;
+ goto on_error;
if ((error = git_filebuf_open(&file, git_str_cstr(&path), GIT_FILEBUF_HASH_CONTENTS, 0666)) < 0)
- return error;
+ goto on_error;
git_array_foreach(roots, idx, oid) {
git_filebuf_write(&file, git_oid_tostr_s(oid), GIT_OID_HEXSZ);
@@ -3378,12 +3378,19 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro
git_filebuf_commit(&file);
- git_str_dispose(&path);
+ if ((error = load_grafts(repo)) < 0) {
+ error = -1;
+ goto on_error;
+ }
- if (load_grafts(repo) < 0)
- return -1;
+ if (git_array_size(roots) == 0) {
+ remove(path.ptr);
+ }
- return 0;
+on_error:
+ git_str_dispose(&path);
+
+ return error;
}
int git_repository_shallow_roots(git_oidarray *out, git_repository *repo)
diff --git a/src/libgit2/transports/smart.c b/src/libgit2/transports/smart.c
index 9d1afeb05..b0925c8bb 100644
--- a/src/libgit2/transports/smart.c
+++ b/src/libgit2/transports/smart.c
@@ -496,17 +496,35 @@ const git_oid * git_shallowarray_get(git_shallowarray *array, size_t idx)
int git_shallowarray_add(git_shallowarray *array, git_oid *oid)
{
size_t oid_index;
+
if (git_array_search(&oid_index, array->array, (git_array_compare_cb)git_oid_cmp, &oid) < 0) {
git_oid *tmp = git_array_alloc(array->array);
+ GIT_ERROR_CHECK_ALLOC(tmp);
+
git_oid_cpy(tmp, oid);
}
+
return 0;
}
int git_shallowarray_remove(git_shallowarray *array, git_oid *oid)
{
- GIT_UNUSED(array);
- GIT_UNUSED(oid);
- /* no git_array_removeā€¦ meh */
- return -1;
+ git_array_oid_t new_array = GIT_ARRAY_INIT;
+ git_oid *element;
+ git_oid *tmp;
+ size_t i;
+
+ git_array_foreach(array->array, i, element) {
+ if (git_oid_cmp(oid, element)) {
+ tmp = git_array_alloc(new_array);
+ GIT_ERROR_CHECK_ALLOC(tmp);
+
+ git_oid_cpy(tmp, element);
+ }
+ }
+
+ git_array_clear(array->array);
+ array->array = new_array;
+
+ return 0;
}