From 83f71b12e1f26943d3c544901846fb1d55785735 Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 26 Jul 2022 16:57:30 +0100 Subject: fix build errors --- src/libgit2/grafts.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++ src/libgit2/grafts.h | 37 ++++++++ src/libgit2/repository.c | 6 +- 3 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 src/libgit2/grafts.c create mode 100644 src/libgit2/grafts.h (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c new file mode 100644 index 000000000..003522616 --- /dev/null +++ b/src/libgit2/grafts.c @@ -0,0 +1,242 @@ +/* + * 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 "grafts.h" + +#include "futils.h" +#include "oidarray.h" +#include "parse.h" + +bool git_shallow__enabled = false; + +struct git_grafts { + /* Map of `git_commit_graft`s */ + git_oidmap *commits; + + /* File backing the graft. NULL if it's an in-memory graft */ + char *path; + git_oid path_checksum; +}; + +int git_grafts_new(git_grafts **out) +{ + git_grafts *grafts; + + grafts = git__calloc(1, sizeof(*grafts)); + GIT_ERROR_CHECK_ALLOC(grafts); + + if ((git_oidmap_new(&grafts->commits)) < 0) { + git__free(grafts); + return -1; + } + + *out = grafts; + return 0; +} + +int git_grafts_from_file(git_grafts **out, const char *path) +{ + git_grafts *grafts = NULL; + int error; + + if ((error = git_grafts_new(&grafts)) < 0) + goto error; + + grafts->path = git__strdup(path); + GIT_ERROR_CHECK_ALLOC(grafts->path); + + if ((error = git_grafts_refresh(grafts)) < 0) + goto error; + + *out = grafts; +error: + if (error < 0) + git_grafts_free(grafts); + return error; +} + +void git_grafts_free(git_grafts *grafts) +{ + if (!grafts) + return; + git__free(grafts->path); + git_grafts_clear(grafts); + git_oidmap_free(grafts->commits); + git__free(grafts); +} + +void git_grafts_clear(git_grafts *grafts) +{ + git_commit_graft *graft; + + assert(grafts); + + git_oidmap_foreach_value(grafts->commits, graft, { + git__free(graft->parents.ptr); + git__free(graft); + }); + + git_oidmap_clear(grafts->commits); +} + +int git_grafts_refresh(git_grafts *grafts) +{ + git_buf contents = GIT_BUF_INIT; + int error, updated = 0; + + assert(grafts); + + if (!grafts->path) + return 0; + + error = git_futils_readbuffer_updated(&contents, grafts->path, + &grafts->path_checksum, &updated); + if (error < 0 || error == GIT_ENOTFOUND || !updated) { + if (error == GIT_ENOTFOUND) { + git_grafts_clear(grafts); + error = 0; + } + goto cleanup; + } + + if ((error = git_grafts_parse(grafts, contents.ptr, contents.size)) < 0) + goto cleanup; + +cleanup: + git_buf_dispose(&contents); + return error; +} + +int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen) +{ + git_array_oid_t parents = GIT_ARRAY_INIT; + git_parse_ctx parser; + int error; + + git_grafts_clear(grafts); + + if ((error = git_parse_ctx_init(&parser, content, contentlen)) < 0) + goto error; + + for (; parser.remain_len; git_parse_advance_line(&parser)) { + const char *line_start = parser.line, *line_end = parser.line + parser.line_len; + git_oid graft_oid; + + if ((error = git_oid_fromstrn(&graft_oid, line_start, GIT_OID_HEXSZ)) < 0) { + git_error_set(GIT_ERROR_GRAFTS, "invalid graft OID at line %" PRIuZ, parser.line_num); + goto error; + } + line_start += GIT_OID_HEXSZ; + + while (line_start < line_end && *line_start == ' ') { + git_oid *id = git_array_alloc(parents); + GIT_ERROR_CHECK_ALLOC(id); + + if ((error = git_oid_fromstrn(id, ++line_start, GIT_OID_HEXSZ)) < 0) { + git_error_set(GIT_ERROR_GRAFTS, "invalid parent OID at line %" PRIuZ, parser.line_num); + goto error; + } + + line_start += GIT_OID_HEXSZ; + } + + if ((error = git_grafts_add(grafts, &graft_oid, parents)) < 0) + goto error; + + git_array_clear(parents); + } + +error: + git_array_clear(parents); + return error; +} + +int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t parents) +{ + git_commit_graft *graft; + git_oid *parent_oid; + int error; + size_t i; + + assert(grafts && oid); + + graft = git__calloc(1, sizeof(*graft)); + GIT_ERROR_CHECK_ALLOC(graft); + + git_array_init_to_size(graft->parents, git_array_size(parents)); + git_array_foreach(parents, i, parent_oid) { + git_oid *id = git_array_alloc(graft->parents); + GIT_ERROR_CHECK_ALLOC(id); + + git_oid_cpy(id, parent_oid); + } + git_oid_cpy(&graft->oid, oid); + + if ((error = git_grafts_remove(grafts, &graft->oid)) < 0 && error != GIT_ENOTFOUND) + goto cleanup; + if ((error = git_oidmap_set(grafts->commits, &graft->oid, graft)) < 0) + goto cleanup; + + return 0; + +cleanup: + git_array_clear(graft->parents); + git__free(graft); + return error; +} + +int git_grafts_remove(git_grafts *grafts, const git_oid *oid) +{ + git_commit_graft *graft; + int error; + + assert(grafts && oid); + + if ((graft = git_oidmap_get(grafts->commits, oid)) == NULL) + return GIT_ENOTFOUND; + + if ((error = git_oidmap_delete(grafts->commits, oid)) < 0) + return error; + + git__free(graft->parents.ptr); + git__free(graft); + + return 0; +} + +int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid) +{ + assert(out && grafts && oid); + if ((*out = git_oidmap_get(grafts->commits, oid)) == NULL) + return GIT_ENOTFOUND; + return 0; +} + +int git_grafts_get_oids(git_oidarray *out, git_grafts *grafts) +{ + git_array_oid_t oids = GIT_ARRAY_INIT; + const git_oid *oid; + size_t i = 0; + int error; + + assert(out && grafts); + + while ((error = git_oidmap_iterate(NULL, grafts->commits, &i, &oid)) == 0) { + git_oid *cpy = git_array_alloc(oids); + GIT_ERROR_CHECK_ALLOC(cpy); + git_oid_cpy(cpy, oid); + } + + git_oidarray__from_array(out, &oids); + + return 0; +} + +size_t git_grafts_size(git_grafts *grafts) +{ + return git_oidmap_size(grafts->commits); +} diff --git a/src/libgit2/grafts.h b/src/libgit2/grafts.h new file mode 100644 index 000000000..fd9ef6736 --- /dev/null +++ b/src/libgit2/grafts.h @@ -0,0 +1,37 @@ +/* + * 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. + */ +#ifndef INCLUDE_graft_h__ +#define INCLUDE_graft_h__ + +#include "common.h" +#include "oidarray.h" +#include "oidmap.h" + +/** graft commit */ +typedef struct { + git_oid oid; + git_array_oid_t parents; +} git_commit_graft; + +typedef struct git_grafts git_grafts; + +extern bool git_shallow__enabled; + +int git_grafts_new(git_grafts **out); +int git_grafts_from_file(git_grafts **out, const char *path); +void git_grafts_free(git_grafts *grafts); +void git_grafts_clear(git_grafts *grafts); + +int git_grafts_refresh(git_grafts *grafts); +int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen); +int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t parents); +int git_grafts_remove(git_grafts *grafts, const git_oid *oid); +int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid); +int git_grafts_get_oids(git_oidarray *out, git_grafts *grafts); +size_t git_grafts_size(git_grafts *grafts); + +#endif diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 2ecc510b2..e58ab529a 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -736,13 +736,13 @@ static int load_grafts(git_repository *repo) int error; if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || - (error = git_buf_joinpath(&path, path.ptr, "grafts")) < 0 || + (error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 || (error = git_grafts_from_file(&repo->grafts, path.ptr)) < 0) goto error; - git_buf_clear(&path); + git_str_clear(&path); - if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0 || + if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0 || (error = git_grafts_from_file(&repo->shallow_grafts, path.ptr)) < 0) goto error; -- cgit v1.2.1 From cfc2ae68b4792f0c64152888869ef69d868079d7 Mon Sep 17 00:00:00 2001 From: yuangli Date: Wed, 27 Jul 2022 11:53:37 +0100 Subject: eliminate build warnings --- src/libgit2/commit.c | 7 +++---- src/libgit2/grafts.c | 6 +++--- src/libgit2/libgit2.c | 2 ++ src/libgit2/repository.c | 6 +++--- 4 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c index 7432ef4ec..2138d6eb2 100644 --- a/src/libgit2/commit.c +++ b/src/libgit2/commit.c @@ -501,8 +501,10 @@ int git_commit__parse_raw(void *commit, const char *data, size_t size) int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags) { - + git_repository *repo = git_object_owner((git_object *)commit); + git_commit_graft *graft; int error; + if ((error = commit_parse(commit, git_odb_object_data(odb_obj), git_odb_object_size(odb_obj), flags)) < 0) return error; @@ -510,9 +512,6 @@ int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned if (!git_shallow__enabled) return 0; - git_repository *repo = git_object_owner((git_object *)commit); - git_commit_graft *graft; - /* Perform necessary grafts */ if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) == 0 || git_grafts_get(&graft, repo->shallow_grafts, git_odb_object_id(odb_obj)) == 0) { diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 003522616..8bcefbab9 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -85,7 +85,7 @@ void git_grafts_clear(git_grafts *grafts) int git_grafts_refresh(git_grafts *grafts) { - git_buf contents = GIT_BUF_INIT; + git_str contents = GIT_STR_INIT; int error, updated = 0; assert(grafts); @@ -94,7 +94,7 @@ int git_grafts_refresh(git_grafts *grafts) return 0; error = git_futils_readbuffer_updated(&contents, grafts->path, - &grafts->path_checksum, &updated); + (grafts->path_checksum).id, &updated); if (error < 0 || error == GIT_ENOTFOUND || !updated) { if (error == GIT_ENOTFOUND) { git_grafts_clear(grafts); @@ -107,7 +107,7 @@ int git_grafts_refresh(git_grafts *grafts) goto cleanup; cleanup: - git_buf_dispose(&contents); + git_str_dispose(&contents); return error; } diff --git a/src/libgit2/libgit2.c b/src/libgit2/libgit2.c index b76728e0c..2537730cf 100644 --- a/src/libgit2/libgit2.c +++ b/src/libgit2/libgit2.c @@ -413,6 +413,8 @@ int git_libgit2_opts(int key, ...) case GIT_OPT_SET_OWNER_VALIDATION: git_repository__validate_ownership = (va_arg(ap, int) != 0); + break; + case GIT_OPT_ENABLE_SHALLOW: git_shallow__enabled = (va_arg(ap, int) != 0); break; diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index e58ab529a..809617276 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -732,10 +732,10 @@ out: static int load_grafts(git_repository *repo) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; - if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || (error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 || (error = git_grafts_from_file(&repo->grafts, path.ptr)) < 0) goto error; @@ -747,7 +747,7 @@ static int load_grafts(git_repository *repo) goto error; error: - git_buf_dispose(&path); + git_str_dispose(&path); return error; } -- cgit v1.2.1 From c01b7841b77c08189eae916d21d591027962a831 Mon Sep 17 00:00:00 2001 From: yuangli Date: Thu, 28 Jul 2022 14:24:18 +0100 Subject: improve error handling --- src/libgit2/grafts.c | 10 +++++++--- src/libgit2/repository.c | 7 ------- src/libgit2/repository.h | 1 - 3 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 8bcefbab9..82be2a680 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -93,13 +93,17 @@ int git_grafts_refresh(git_grafts *grafts) if (!grafts->path) return 0; - error = git_futils_readbuffer_updated(&contents, grafts->path, - (grafts->path_checksum).id, &updated); - if (error < 0 || error == GIT_ENOTFOUND || !updated) { + if ((error = git_futils_readbuffer_updated(&contents, grafts->path, + (grafts->path_checksum).id, &updated)) < 0) { if (error == GIT_ENOTFOUND) { git_grafts_clear(grafts); error = 0; } + + goto cleanup; + } + + if (!updated) { goto cleanup; } diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 809617276..c36666c43 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -735,13 +735,6 @@ static int load_grafts(git_repository *repo) git_str path = GIT_STR_INIT; int error; - if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || - (error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 || - (error = git_grafts_from_file(&repo->grafts, path.ptr)) < 0) - goto error; - - git_str_clear(&path); - if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0 || (error = git_grafts_from_file(&repo->shallow_grafts, path.ptr)) < 0) goto error; diff --git a/src/libgit2/repository.h b/src/libgit2/repository.h index 6d39bb92a..3cca53b3e 100644 --- a/src/libgit2/repository.h +++ b/src/libgit2/repository.h @@ -25,7 +25,6 @@ #include "submodule.h" #include "diff_driver.h" #include "grafts.h" -#include "oidarray.h" #define DOT_GIT ".git" #define GIT_DIR DOT_GIT "/" -- cgit v1.2.1 From 14d2a60a5bdb6fe62b65751bda0ce01a66ac5e99 Mon Sep 17 00:00:00 2001 From: yuangli Date: Thu, 28 Jul 2022 14:30:30 +0100 Subject: fix load_grafts --- src/libgit2/repository.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/libgit2') diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index c36666c43..809617276 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -735,6 +735,13 @@ static int load_grafts(git_repository *repo) git_str path = GIT_STR_INIT; int error; + if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + (error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 || + (error = git_grafts_from_file(&repo->grafts, path.ptr)) < 0) + goto error; + + git_str_clear(&path); + if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0 || (error = git_grafts_from_file(&repo->shallow_grafts, path.ptr)) < 0) goto error; -- cgit v1.2.1 From 62cc77a16d62410140e31960189e566f16b22772 Mon Sep 17 00:00:00 2001 From: yuangli Date: Thu, 28 Jul 2022 16:03:59 +0100 Subject: refactor commit parent assignment with graft --- src/libgit2/commit.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c index 2138d6eb2..6f689e362 100644 --- a/src/libgit2/commit.c +++ b/src/libgit2/commit.c @@ -499,6 +499,22 @@ int git_commit__parse_raw(void *commit, const char *data, size_t size) return commit_parse(commit, data, size, 0); } +static int assign_parents_from_graft(git_commit *commit, git_commit_graft *graft) { + size_t idx; + git_oid *oid; + + git_array_clear(commit->parent_ids); + git_array_init_to_size(commit->parent_ids, git_array_size(graft->parents)); + git_array_foreach(graft->parents, idx, oid) { + git_oid *id = git_array_alloc(commit->parent_ids); + GIT_ERROR_CHECK_ALLOC(id); + + git_oid_cpy(id, oid); + } + + return 0; +} + int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags) { git_repository *repo = git_object_owner((git_object *)commit); @@ -513,21 +529,11 @@ int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned return 0; /* Perform necessary grafts */ - if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) == 0 || - git_grafts_get(&graft, repo->shallow_grafts, git_odb_object_id(odb_obj)) == 0) { - size_t idx; - git_oid *oid; - git_array_clear(commit->parent_ids); - git_array_init_to_size(commit->parent_ids, git_array_size(graft->parents)); - git_array_foreach(graft->parents, idx, oid) { - git_oid *id = git_array_alloc(commit->parent_ids); - GIT_ERROR_CHECK_ALLOC(id); - - git_oid_cpy(id, oid); - } - } - - return 0; + if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) != 0 && + git_grafts_get(&graft, repo->shallow_grafts, git_odb_object_id(odb_obj)) != 0) + return 0; + + return assign_parents_from_graft(commit, graft); } int git_commit__parse(void *_commit, git_odb_object *odb_obj) -- cgit v1.2.1 From a544a91058cc310a0e36e290debe5ad59040fab1 Mon Sep 17 00:00:00 2001 From: yuangli Date: Thu, 28 Jul 2022 16:05:21 +0100 Subject: rename function assign_parents_from_graft --- src/libgit2/commit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c index 6f689e362..43d04b2c0 100644 --- a/src/libgit2/commit.c +++ b/src/libgit2/commit.c @@ -499,7 +499,7 @@ int git_commit__parse_raw(void *commit, const char *data, size_t size) return commit_parse(commit, data, size, 0); } -static int assign_parents_from_graft(git_commit *commit, git_commit_graft *graft) { +static int assign_commit_parents_from_graft(git_commit *commit, git_commit_graft *graft) { size_t idx; git_oid *oid; @@ -533,7 +533,7 @@ int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned git_grafts_get(&graft, repo->shallow_grafts, git_odb_object_id(odb_obj)) != 0) return 0; - return assign_parents_from_graft(commit, graft); + return assign_commit_parents_from_graft(commit, graft); } int git_commit__parse(void *_commit, git_odb_object *odb_obj) -- cgit v1.2.1 From 73d25f0e7b026d7b744e249d922f248376bcce5d Mon Sep 17 00:00:00 2001 From: yuangli Date: Fri, 29 Jul 2022 13:53:29 +0100 Subject: remove build errors --- src/libgit2/clone.c | 2 +- src/libgit2/commit.c | 2 +- src/libgit2/fetch.c | 7 +-- src/libgit2/repository.c | 109 +------------------------------------ src/libgit2/transports/smart_pkt.c | 16 +++--- 5 files changed, 14 insertions(+), 122 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/clone.c b/src/libgit2/clone.c index 101c741b1..ee1f2b892 100644 --- a/src/libgit2/clone.c +++ b/src/libgit2/clone.c @@ -411,7 +411,7 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch fetch_opts.update_fetchhead = 0; if (fetch_opts.depth == -1) fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; - git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); + git_str_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); if ((error = git_remote_fetch(remote, NULL, &fetch_opts, git_str_cstr(&reflog_message))) != 0) goto cleanup; diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c index 75cc8837c..528d8beb7 100644 --- a/src/libgit2/commit.c +++ b/src/libgit2/commit.c @@ -422,7 +422,7 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig buffer += tree_len; } - while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) { + while (git_object__parse_oid_header(&parent_id, &buffer, buffer_end, "parent ", GIT_OID_SHA1) == 0) { git_oid *new_id = git_array_alloc(commit->parent_ids); GIT_ERROR_CHECK_ALLOC(new_id); diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index 10155662d..e4a8f0382 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -209,12 +209,7 @@ int git_fetch_download_pack(git_remote *remote) if (!remote->need_pack) return 0; - if (callbacks) { - progress = callbacks->transfer_progress; - payload = callbacks->payload; - } - - if ((error = t->download_pack(t, remote->repo, &remote->stats, progress, payload)) < 0) + if ((error = t->download_pack(t, remote->repo, &remote->stats)) < 0) return error; if ((error = git_repository__shallow_roots_write(remote->repo, remote->nego.shallow_roots->array)) < 0) diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index adb4721ad..d9bc537fe 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3340,109 +3340,6 @@ int git_repository_state_cleanup(git_repository *repo) return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files)); } -// int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo) -// { -// git_buf path = GIT_BUF_INIT; -// git_buf contents = GIT_BUF_INIT; -// int error, updated, line_num = 1; -// char *line; -// chror = git_futils_readbuffer_updated(&contents, git_buf_cstr(&path), &repo->shallow_grafts->git_grafts->path_checksum, &updated); -// git_buf_dispose(&path); - -// if (error < 0 && error != GIT_ENOTFOUND) -// return error; - -// /* cancel out GIT_ENOTFOUND */ -// git_error_clear(); -// error = 0; - -// if (!updated) { -// out = repo->shallow_grafts; -// goto cleanup; -// } - -// git_array_clear(repo->shallow_grafts); - -// buffer = contents.ptr; -// while ((line = git__strsep(&buffer, "\n")) != NULL) { -// git_oid *oid = git_array_alloc(repo->shallow_grafts); - -// error = git_oid_fromstr(oid, line); -// if (error < 0) { -// git_error_set(GIT_ERROR_REPOSITORY, "Invalid OID at line %d", line_num); -// git_array_clear(repo->shallow_grafts); -// error = -1; -// goto cleanup; -// } -// ++line_num; -// } - -// if (*buffer) { -// git_error_set(GIT_ERROR_REPOSITORY, "No EOL at line %d", line_num); -// git_array_clear(repo->shallow_grafts); -// error = -1; -// goto cleanup; -// } - -// *out = repo->shallow_grafts; - -// cleanup: -// git_buf_dispose(&contents); - -// return error;ar *buffer; - -// assert(out && repo); - -// if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0) -// return error; - -// //error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&path), &repo->shallow_checksum, &updated); -// error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&path), &repo->shallow_grafts->git_grafts->path_checksum, &updated); -// git_buf_dispose(&path); - -// if (error < 0 && error != GIT_ENOTFOUND) -// return error; - -// /* cancel out GIT_ENOTFOUND */ -// git_error_clear(); -// error = 0; - -// if (!updated) { -// out = repo->shallow_grafts; -// goto cleanup; -// } - -// git_array_clear(repo->shallow_grafts); - -// buffer = contents.ptr; -// while ((line = git__strsep(&buffer, "\n")) != NULL) { -// git_oid *oid = git_array_alloc(repo->shallow_grafts); - -// error = git_oid_fromstr(oid, line); -// if (error < 0) { -// git_error_set(GIT_ERROR_REPOSITORY, "Invalid OID at line %d", line_num); -// git_array_clear(repo->shallow_grafts); -// error = -1; -// goto cleanup; -// } -// ++line_num; -// } - -// if (*buffer) { -// git_error_set(GIT_ERROR_REPOSITORY, "No EOL at line %d", line_num); -// git_array_clear(repo->shallow_grafts); -// error = -1; -// goto cleanup; -// } - -// *out = repo->shallow_grafts; - -// cleanup: -// git_buf_dispose(&contents); - -// return error; -// } - int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo) { int error =0; if (!repo->shallow_grafts) @@ -3455,17 +3352,17 @@ int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo) { int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t roots) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error = 0; size_t idx; git_oid *oid; assert(repo); - if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0) + if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0) return error; - if ((error = git_filebuf_open(&file, git_buf_cstr(&path), GIT_FILEBUF_HASH_CONTENTS, 0666)) < 0) + if ((error = git_filebuf_open(&file, git_str_cstr(&path), GIT_FILEBUF_HASH_CONTENTS, 0666)) < 0) return error; git_array_foreach(roots, idx, oid) { diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index e368cb7e2..f9fde00f1 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -678,23 +678,23 @@ int git_pkt_buffer_wants( git_buf shallow_buf = GIT_BUF_INIT; git_oid_fmt(oid, git_shallowarray_get(wants->shallow_roots, i)); - git_buf_puts(&shallow_buf, "shallow "); - git_buf_put(&shallow_buf, oid, GIT_OID_HEXSZ); - git_buf_putc(&shallow_buf, '\n'); + git_str_puts(&shallow_buf, "shallow "); + git_str_put(&shallow_buf, oid, GIT_OID_HEXSZ); + git_str_putc(&shallow_buf, '\n'); - git_buf_printf(buf, "%04x%s", (unsigned int)git_buf_len(&shallow_buf) + 4, git_buf_cstr(&shallow_buf)); + git_str_printf(buf, "%04x%s", (unsigned int)git_str_len(&shallow_buf) + 4, git_str_cstr(&shallow_buf)); - if (git_buf_oom(buf)) + if (git_str_oom(buf)) return -1; } if (wants->depth > 0) { git_buf deepen_buf = GIT_BUF_INIT; - git_buf_printf(&deepen_buf, "deepen %d\n", wants->depth); - git_buf_printf(buf,"%04x%s", (unsigned int)git_buf_len(&deepen_buf) + 4, git_buf_cstr(&deepen_buf)); + git_str_printf(&deepen_buf, "deepen %d\n", wants->depth); + git_str_printf(buf,"%04x%s", (unsigned int)git_str_len(&deepen_buf) + 4, git_str_cstr(&deepen_buf)); - if (git_buf_oom(buf)) + if (git_str_oom(buf)) return -1; } -- cgit v1.2.1 From 598ec303c6862f581c22c49228d543442e30257a Mon Sep 17 00:00:00 2001 From: yuangli Date: Fri, 29 Jul 2022 15:04:17 +0100 Subject: eliminate build warnings --- src/libgit2/fetch.c | 2 -- src/libgit2/grafts.c | 7 ++----- src/libgit2/grafts.h | 2 +- src/libgit2/repository.c | 18 +++++++++++++----- src/libgit2/transports/smart_pkt.c | 4 ++-- 5 files changed, 18 insertions(+), 15 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index e4a8f0382..b90ce2ee8 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -202,8 +202,6 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) int git_fetch_download_pack(git_remote *remote) { git_transport *t = remote->transport; - git_indexer_progress_cb progress = NULL; - void *payload = NULL; int error; if (!remote->need_pack) diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 82be2a680..f1054fa36 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -220,9 +220,8 @@ int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oi return 0; } -int git_grafts_get_oids(git_oidarray *out, git_grafts *grafts) +int git_grafts_get_oids(git_array_oid_t *out, git_grafts *grafts) { - git_array_oid_t oids = GIT_ARRAY_INIT; const git_oid *oid; size_t i = 0; int error; @@ -230,13 +229,11 @@ int git_grafts_get_oids(git_oidarray *out, git_grafts *grafts) assert(out && grafts); while ((error = git_oidmap_iterate(NULL, grafts->commits, &i, &oid)) == 0) { - git_oid *cpy = git_array_alloc(oids); + git_oid *cpy = git_array_alloc(*out); GIT_ERROR_CHECK_ALLOC(cpy); git_oid_cpy(cpy, oid); } - git_oidarray__from_array(out, &oids); - return 0; } diff --git a/src/libgit2/grafts.h b/src/libgit2/grafts.h index fd9ef6736..4139438bb 100644 --- a/src/libgit2/grafts.h +++ b/src/libgit2/grafts.h @@ -31,7 +31,7 @@ int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen) int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t parents); int git_grafts_remove(git_grafts *grafts, const git_oid *oid); int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid); -int git_grafts_get_oids(git_oidarray *out, git_grafts *grafts); +int git_grafts_get_oids(git_array_oid_t *out, git_grafts *grafts); size_t git_grafts_size(git_grafts *grafts); #endif diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index d9bc537fe..bc2aba324 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3341,12 +3341,20 @@ int git_repository_state_cleanup(git_repository *repo) } int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo) { - int error =0; - if (!repo->shallow_grafts) - load_grafts(repo); + int error = 0; + + if (!repo->shallow_grafts && (error = load_grafts(repo)) < 0) + return error; + + if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0) { + return error; + } - git_grafts_refresh(repo->shallow_grafts); - return git_grafts_get_oids(out, repo->shallow_grafts); + if ((error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) { + return error; + } + + return 0; } int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t roots) diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index f9fde00f1..951356c29 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -675,7 +675,7 @@ int git_pkt_buffer_wants( /* Tell the server about our shallow objects */ for (i = 0; i < git_shallowarray_count(wants->shallow_roots); i++) { char oid[GIT_OID_HEXSZ]; - git_buf shallow_buf = GIT_BUF_INIT; + git_str shallow_buf = GIT_STR_INIT; git_oid_fmt(oid, git_shallowarray_get(wants->shallow_roots, i)); git_str_puts(&shallow_buf, "shallow "); @@ -689,7 +689,7 @@ int git_pkt_buffer_wants( } if (wants->depth > 0) { - git_buf deepen_buf = GIT_BUF_INIT; + git_str deepen_buf = GIT_STR_INIT; git_str_printf(&deepen_buf, "deepen %d\n", wants->depth); git_str_printf(buf,"%04x%s", (unsigned int)git_str_len(&deepen_buf) + 4, git_str_cstr(&deepen_buf)); -- cgit v1.2.1 From 179aac788d45d3683a93ad478bfb7371c549ca98 Mon Sep 17 00:00:00 2001 From: yuangli Date: Fri, 29 Jul 2022 16:04:43 +0100 Subject: fix clone::shallow test behaviour --- src/libgit2/transports/smart_protocol.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c index cd90db43f..f2a6ac508 100644 --- a/src/libgit2/transports/smart_protocol.c +++ b/src/libgit2/transports/smart_protocol.c @@ -375,10 +375,8 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c while ((error = recv_pkt((git_pkt **)&pkt, NULL, buf)) == 0) { if (pkt->type == GIT_PKT_SHALLOW) { - printf("shallow %s\n", git_oid_tostr_s(&pkt->oid)); git_shallowarray_add(wants->shallow_roots, &pkt->oid); } else if (pkt->type == GIT_PKT_UNSHALLOW) { - printf("unshallow %s\n", git_oid_tostr_s(&pkt->oid)); git_shallowarray_remove(wants->shallow_roots, &pkt->oid); } else if (pkt->type == GIT_PKT_FLUSH) { /* Server is done, stop processing shallow oids */ -- cgit v1.2.1 From e7294e870398d72b79a436b628170ffcaaa1713c Mon Sep 17 00:00:00 2001 From: yuangli Date: Mon, 1 Aug 2022 21:42:11 +0100 Subject: fix memory leaks about packets --- src/libgit2/transports/smart_pkt.c | 2 ++ src/libgit2/transports/smart_protocol.c | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index 951356c29..5808b8816 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -694,6 +694,8 @@ int git_pkt_buffer_wants( git_str_printf(&deepen_buf, "deepen %d\n", wants->depth); git_str_printf(buf,"%04x%s", (unsigned int)git_str_len(&deepen_buf) + 4, git_str_cstr(&deepen_buf)); + git_str_dispose(&deepen_buf); + if (git_str_oom(buf)) return -1; } diff --git a/src/libgit2/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c index f2a6ac508..a44d0c853 100644 --- a/src/libgit2/transports/smart_protocol.c +++ b/src/libgit2/transports/smart_protocol.c @@ -385,8 +385,12 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c git_error_set(GIT_ERROR_NET, "Unexpected pkt type"); goto on_error; } + + git_pkt_free((git_pkt *) pkt); } + git_pkt_free((git_pkt *) pkt); + if (error < 0) { goto on_error; } -- cgit v1.2.1 From 2d33fe78858354c508afb77d80f32a5a747b801e Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 2 Aug 2022 13:15:22 +0100 Subject: refactor git_fetch_option.depth and usage --- src/libgit2/clone.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/libgit2') diff --git a/src/libgit2/clone.c b/src/libgit2/clone.c index ee1f2b892..95bddeae6 100644 --- a/src/libgit2/clone.c +++ b/src/libgit2/clone.c @@ -389,6 +389,11 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c return error; } +static int git_fetch_is_shallow(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; @@ -409,8 +414,10 @@ 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 (fetch_opts.depth == -1) + + if (!git_fetch_is_shallow(opts)) fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; + git_str_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); if ((error = git_remote_fetch(remote, NULL, &fetch_opts, git_str_cstr(&reflog_message))) != 0) -- cgit v1.2.1 From 4536477ee1f884501717b3a4a67da3bc4974e7f8 Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 2 Aug 2022 14:35:08 +0100 Subject: fix memory leak --- src/libgit2/repository.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libgit2') diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index bc2aba324..105ea647f 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3380,6 +3380,8 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro git_filebuf_commit(&file); + git_str_dispose(&path); + if (load_grafts(repo) < 0) return -1; -- cgit v1.2.1 From e93d0815a8de2806667851e31dbd06578db00f95 Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 2 Aug 2022 14:35:27 +0100 Subject: attempt to fix nego.shallowarray memory leak --- src/libgit2/remote.c | 3 +++ src/libgit2/transports/smart.c | 6 ++++++ src/libgit2/transports/smart.h | 2 ++ 3 files changed, 11 insertions(+) (limited to 'src/libgit2') diff --git a/src/libgit2/remote.c b/src/libgit2/remote.c index 02d271d7d..c3d3af530 100644 --- a/src/libgit2/remote.c +++ b/src/libgit2/remote.c @@ -22,6 +22,7 @@ #include "git2/types.h" #include "git2/oid.h" #include "git2/net.h" +#include "transports/smart.h" #define CONFIG_URL_FMT "remote.%s.url" #define CONFIG_PUSHURL_FMT "remote.%s.pushurl" @@ -2163,6 +2164,8 @@ void git_remote_free(git_remote *remote) free_heads(&remote->local_heads); git_vector_free(&remote->local_heads); + git_shallowarray_free((remote->nego).shallow_roots); + git_push_free(remote->push); git__free(remote->url); git__free(remote->pushurl); diff --git a/src/libgit2/transports/smart.c b/src/libgit2/transports/smart.c index 9d1afeb05..df8e4da4a 100644 --- a/src/libgit2/transports/smart.c +++ b/src/libgit2/transports/smart.c @@ -510,3 +510,9 @@ int git_shallowarray_remove(git_shallowarray *array, git_oid *oid) /* no git_array_remove… meh */ return -1; } + +void git_shallowarray_free(git_shallowarray *array) +{ + git_array_clear(array->array); + git__free(array); +} diff --git a/src/libgit2/transports/smart.h b/src/libgit2/transports/smart.h index bc072d2fe..f9577cdee 100644 --- a/src/libgit2/transports/smart.h +++ b/src/libgit2/transports/smart.h @@ -203,4 +203,6 @@ struct git_shallowarray { git_array_oid_t array; }; +void git_shallowarray_free(git_shallowarray *array); + #endif -- cgit v1.2.1 From da04d3fc5e737b990e884129241f2ea3cba4cf6a Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 2 Aug 2022 16:30:48 +0100 Subject: fix grafts and shallowarray memory leaks --- src/libgit2/grafts.c | 3 +++ src/libgit2/remote.c | 7 +++++-- src/libgit2/repository.c | 6 ++---- src/libgit2/transports/smart.c | 6 ------ src/libgit2/transports/smart.h | 2 -- 5 files changed, 10 insertions(+), 14 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index f1054fa36..dd1be3434 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -43,6 +43,9 @@ int git_grafts_from_file(git_grafts **out, const char *path) git_grafts *grafts = NULL; int error; + if (*out) + return git_grafts_refresh(*out); + if ((error = git_grafts_new(&grafts)) < 0) goto error; diff --git a/src/libgit2/remote.c b/src/libgit2/remote.c index c3d3af530..63346e941 100644 --- a/src/libgit2/remote.c +++ b/src/libgit2/remote.c @@ -2150,6 +2150,11 @@ void git_remote_free(git_remote *remote) remote->transport = NULL; } + if (remote->nego.shallow_roots) { + git_array_clear(remote->nego.shallow_roots->array); + git__free(remote->nego.shallow_roots); + } + git_vector_free(&remote->refs); free_refspecs(&remote->refspecs); @@ -2164,8 +2169,6 @@ void git_remote_free(git_remote *remote) free_heads(&remote->local_heads); git_vector_free(&remote->local_heads); - git_shallowarray_free((remote->nego).shallow_roots); - git_push_free(remote->push); git__free(remote->url); git__free(remote->pushurl); diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 105ea647f..0d149a626 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3346,13 +3346,11 @@ int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo) { if (!repo->shallow_grafts && (error = load_grafts(repo)) < 0) return error; - if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0) { + if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0) return error; - } - if ((error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) { + if ((error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) return error; - } return 0; } diff --git a/src/libgit2/transports/smart.c b/src/libgit2/transports/smart.c index df8e4da4a..9d1afeb05 100644 --- a/src/libgit2/transports/smart.c +++ b/src/libgit2/transports/smart.c @@ -510,9 +510,3 @@ int git_shallowarray_remove(git_shallowarray *array, git_oid *oid) /* no git_array_remove… meh */ return -1; } - -void git_shallowarray_free(git_shallowarray *array) -{ - git_array_clear(array->array); - git__free(array); -} diff --git a/src/libgit2/transports/smart.h b/src/libgit2/transports/smart.h index f9577cdee..bc072d2fe 100644 --- a/src/libgit2/transports/smart.h +++ b/src/libgit2/transports/smart.h @@ -203,6 +203,4 @@ struct git_shallowarray { git_array_oid_t array; }; -void git_shallowarray_free(git_shallowarray *array); - #endif -- cgit v1.2.1 From 8ef492fafcc05ccfa90481057eccc8ba4f5e730a Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 2 Aug 2022 16:46:44 +0100 Subject: fix build warning --- src/libgit2/clone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libgit2') diff --git a/src/libgit2/clone.c b/src/libgit2/clone.c index 95bddeae6..5e07dc733 100644 --- a/src/libgit2/clone.c +++ b/src/libgit2/clone.c @@ -389,7 +389,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c return error; } -static int git_fetch_is_shallow(git_fetch_options *opts) +static int git_fetch_is_shallow(const git_fetch_options *opts) { return opts->depth > 0; } -- cgit v1.2.1 From 09b3d33d6dba7f4804b478a72dec3258405856c2 Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 9 Aug 2022 19:23:54 +0100 Subject: fix memory leak --- src/libgit2/transports/smart_pkt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index 5808b8816..832da450c 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -684,6 +684,8 @@ int git_pkt_buffer_wants( git_str_printf(buf, "%04x%s", (unsigned int)git_str_len(&shallow_buf) + 4, git_str_cstr(&shallow_buf)); + git_str_dispose(&shallow_buf); + if (git_str_oom(buf)) return -1; } -- cgit v1.2.1 From df5eb3239b1419b3f4382d7bcca9a5d85611d7d3 Mon Sep 17 00:00:00 2001 From: yuangli Date: Tue, 9 Aug 2022 19:24:57 +0100 Subject: support fetch unshallow option on shallow repos --- src/libgit2/clone.c | 7 +------ src/libgit2/fetch.c | 9 +++++++-- src/libgit2/repository.c | 19 +++++++++++++------ src/libgit2/transports/smart.c | 26 ++++++++++++++++++++++---- 4 files changed, 43 insertions(+), 18 deletions(-) (limited to 'src/libgit2') 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; } -- cgit v1.2.1 From 49e641be8c5549f6f5731d6d72e9e6902e71d0e1 Mon Sep 17 00:00:00 2001 From: yuangli Date: Thu, 11 Aug 2022 09:32:28 +0100 Subject: remove unused api --- src/libgit2/repository.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 13559ef07..6b77007aa 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3393,20 +3393,6 @@ on_error: return error; } -int git_repository_shallow_roots(git_oidarray *out, git_repository *repo) -{ - int ret; - git_array_oid_t array = GIT_ARRAY_INIT; - - assert(out); - - ret = git_repository__shallow_roots(&array, repo); - - git_oidarray__from_array(out, &array); - - return ret; -} - int git_repository_is_shallow(git_repository *repo) { git_str path = GIT_STR_INIT; -- cgit v1.2.1 From 8b521f018b734f58db2b9aec184e0f96422f140e Mon Sep 17 00:00:00 2001 From: yuangli Date: Thu, 11 Aug 2022 09:38:21 +0100 Subject: document unshallow behaviour in fetch.c --- src/libgit2/fetch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index a015cfbd3..3216b261c 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -60,7 +60,9 @@ static int mark_local(git_remote *remote) return -1; git_vector_foreach(&remote->refs, i, head) { - /* If we have the object, mark it so we don't ask for it */ + /* If we have the object, mark it so we don't ask for it. + However if we are unshallowing, we need to ask for it + even though the head exists locally. */ if (remote->nego.depth != INT_MAX && git_odb_exists(odb, &head->oid)) head->local = 1; else -- cgit v1.2.1 From a3bfd284c2d49ef148a7e12fbeb0134b5246b5e6 Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Wed, 31 Aug 2022 11:09:49 +0100 Subject: Use GIT_OID_SHA1_HEXSIZE --- src/libgit2/grafts.c | 8 ++++---- src/libgit2/repository.c | 2 +- src/libgit2/transports/smart_pkt.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index dd1be3434..5b078b01d 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -133,22 +133,22 @@ int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen) const char *line_start = parser.line, *line_end = parser.line + parser.line_len; git_oid graft_oid; - if ((error = git_oid_fromstrn(&graft_oid, line_start, GIT_OID_HEXSZ)) < 0) { + if ((error = git_oid_fromstrn(&graft_oid, line_start, GIT_OID_SHA1_HEXSIZE)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid graft OID at line %" PRIuZ, parser.line_num); goto error; } - line_start += GIT_OID_HEXSZ; + line_start += GIT_OID_SHA1_HEXSIZE; while (line_start < line_end && *line_start == ' ') { git_oid *id = git_array_alloc(parents); GIT_ERROR_CHECK_ALLOC(id); - if ((error = git_oid_fromstrn(id, ++line_start, GIT_OID_HEXSZ)) < 0) { + if ((error = git_oid_fromstrn(id, ++line_start, GIT_OID_SHA1_HEXSIZE)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid parent OID at line %" PRIuZ, parser.line_num); goto error; } - line_start += GIT_OID_HEXSZ; + line_start += GIT_OID_SHA1_HEXSIZE; } if ((error = git_grafts_add(grafts, &graft_oid, parents)) < 0) diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 6b77007aa..0eb16c223 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3372,7 +3372,7 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro goto on_error; git_array_foreach(roots, idx, oid) { - git_filebuf_write(&file, git_oid_tostr_s(oid), GIT_OID_HEXSZ); + git_filebuf_write(&file, git_oid_tostr_s(oid), GIT_OID_SHA1_HEXSIZE); git_filebuf_write(&file, "\n", 1); } diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index 832da450c..cfdf36244 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -377,10 +377,10 @@ static int shallow_pkt(git_pkt **out, const char *line, size_t len) line += 7; len -= 7; - if (len >= GIT_OID_HEXSZ) { + if (len >= GIT_OID_SHA1_HEXSIZE) { git_oid_fromstr(&pkt->oid, line + 1); - line += GIT_OID_HEXSZ + 1; - len -= GIT_OID_HEXSZ + 1; + line += GIT_OID_SHA1_HEXSIZE + 1; + len -= GIT_OID_SHA1_HEXSIZE + 1; } *out = (git_pkt *) pkt; @@ -399,10 +399,10 @@ static int unshallow_pkt(git_pkt **out, const char *line, size_t len) line += 9; len -= 9; - if (len >= GIT_OID_HEXSZ) { + if (len >= GIT_OID_SHA1_HEXSIZE) { git_oid_fromstr(&pkt->oid, line + 1); - line += GIT_OID_HEXSZ + 1; - len -= GIT_OID_HEXSZ + 1; + line += GIT_OID_SHA1_HEXSIZE + 1; + len -= GIT_OID_SHA1_HEXSIZE + 1; } *out = (git_pkt *) pkt; @@ -674,12 +674,12 @@ int git_pkt_buffer_wants( /* Tell the server about our shallow objects */ for (i = 0; i < git_shallowarray_count(wants->shallow_roots); i++) { - char oid[GIT_OID_HEXSZ]; + char oid[GIT_OID_SHA1_HEXSIZE]; git_str shallow_buf = GIT_STR_INIT; git_oid_fmt(oid, git_shallowarray_get(wants->shallow_roots, i)); git_str_puts(&shallow_buf, "shallow "); - git_str_put(&shallow_buf, oid, GIT_OID_HEXSZ); + git_str_put(&shallow_buf, oid, GIT_OID_SHA1_HEXSIZE); git_str_putc(&shallow_buf, '\n'); git_str_printf(buf, "%04x%s", (unsigned int)git_str_len(&shallow_buf) + 4, git_str_cstr(&shallow_buf)); -- cgit v1.2.1 From f1f9b45dd20b408953eac2d515e8dfa0264aa631 Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Wed, 31 Aug 2022 15:34:06 +0100 Subject: fix test failures --- src/libgit2/fetch.c | 6 ++++-- src/libgit2/grafts.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index 3216b261c..69794ed1f 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -21,6 +21,7 @@ #include "repository.h" #include "refs.h" #include "transports/smart.h" +#include static int maybe_want(git_remote *remote, git_remote_head *head, git_refspec *tagspec, git_remote_autotag_option_t tagopt) { @@ -175,7 +176,8 @@ 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; + + remote->nego.depth = (opts && !opts->unshallow) ? opts->depth : INT_MAX; if (filter_wants(remote, opts) < 0) return -1; @@ -184,7 +186,7 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) if (!remote->need_pack) return 0; - if (opts->unshallow && opts->depth > 0) { + if (opts && opts->unshallow && opts->depth > 0) { git_error_set(GIT_ERROR_INVALID, "options '--depth' and '--unshallow' cannot be used together"); return -1; } diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 5b078b01d..6662f5009 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -133,7 +133,7 @@ int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen) const char *line_start = parser.line, *line_end = parser.line + parser.line_len; git_oid graft_oid; - if ((error = git_oid_fromstrn(&graft_oid, line_start, GIT_OID_SHA1_HEXSIZE)) < 0) { + if ((error = git_oid__fromstrn(&graft_oid, line_start, GIT_OID_SHA1_HEXSIZE, GIT_OID_SHA1)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid graft OID at line %" PRIuZ, parser.line_num); goto error; } @@ -143,7 +143,7 @@ int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen) git_oid *id = git_array_alloc(parents); GIT_ERROR_CHECK_ALLOC(id); - if ((error = git_oid_fromstrn(id, ++line_start, GIT_OID_SHA1_HEXSIZE)) < 0) { + if ((error = git_oid__fromstrn(id, ++line_start, GIT_OID_SHA1_HEXSIZE, GIT_OID_SHA1)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid parent OID at line %" PRIuZ, parser.line_num); goto error; } -- cgit v1.2.1 From 6c46b58e9b284c536168c8b333bbcf50c3431f83 Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Wed, 31 Aug 2022 15:39:33 +0100 Subject: include oid.h in grafts.c --- src/libgit2/grafts.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 6662f5009..7cbb1dd76 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -8,6 +8,7 @@ #include "grafts.h" #include "futils.h" +#include "oid.h" #include "oidarray.h" #include "parse.h" -- cgit v1.2.1 From 4cf19add64e2a705bdf1c87ece4874edef77d290 Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Wed, 31 Aug 2022 16:02:42 +0100 Subject: refactor smart_pkt --- src/libgit2/transports/smart_pkt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index cfdf36244..9e9bda020 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -378,7 +378,7 @@ static int shallow_pkt(git_pkt **out, const char *line, size_t len) len -= 7; if (len >= GIT_OID_SHA1_HEXSIZE) { - git_oid_fromstr(&pkt->oid, line + 1); + git_oid__fromstr(&pkt->oid, line + 1, GIT_OID_SHA1); line += GIT_OID_SHA1_HEXSIZE + 1; len -= GIT_OID_SHA1_HEXSIZE + 1; } @@ -400,7 +400,7 @@ static int unshallow_pkt(git_pkt **out, const char *line, size_t len) len -= 9; if (len >= GIT_OID_SHA1_HEXSIZE) { - git_oid_fromstr(&pkt->oid, line + 1); + git_oid__fromstr(&pkt->oid, line + 1, GIT_OID_SHA1); line += GIT_OID_SHA1_HEXSIZE + 1; len -= GIT_OID_SHA1_HEXSIZE + 1; } -- cgit v1.2.1 From 7122fcd2e4da67905df0d293d0223371b4ffdf01 Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Mon, 5 Sep 2022 16:24:38 +0100 Subject: fix depth initialisation --- src/libgit2/fetch.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index 69794ed1f..df8f0a154 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -62,8 +62,8 @@ 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. - However if we are unshallowing, we need to ask for it - even though the head exists locally. */ + However if we are unshallowing, we need to ask for it + even though the head exists locally. */ if (remote->nego.depth != INT_MAX && git_odb_exists(odb, &head->oid)) head->local = 1; else @@ -177,7 +177,10 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) remote->need_pack = 0; - remote->nego.depth = (opts && !opts->unshallow) ? opts->depth : INT_MAX; + if (!opts) + remote->nego.depth = -1; + else + remote->nego.depth = opts->unshallow ? INT_MAX : opts->depth; if (filter_wants(remote, opts) < 0) return -1; -- cgit v1.2.1 From 47f36a937f2ea5c3dc33ed940057134af967b062 Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Mon, 5 Sep 2022 19:28:29 +0100 Subject: fix error handling --- src/libgit2/fetch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index df8f0a154..874813b4e 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -219,10 +219,10 @@ int git_fetch_download_pack(git_remote *remote) if (!remote->need_pack) return 0; - if ((error = t->download_pack(t, remote->repo, &remote->stats)) < 0) + if ((error = t->download_pack(t, remote->repo, &remote->stats)) != 0) return error; - if ((error = git_repository__shallow_roots_write(remote->repo, remote->nego.shallow_roots->array)) < 0) + if ((error = git_repository__shallow_roots_write(remote->repo, remote->nego.shallow_roots->array)) != 0) return error; return 0; -- cgit v1.2.1 From d23a7903d107528f9d62608f9b236251d9756b00 Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Mon, 5 Sep 2022 19:44:49 +0100 Subject: remove unused statements --- src/libgit2/fetch.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index 874813b4e..2a419534e 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -21,7 +21,6 @@ #include "repository.h" #include "refs.h" #include "transports/smart.h" -#include static int maybe_want(git_remote *remote, git_remote_head *head, git_refspec *tagspec, git_remote_autotag_option_t tagopt) { -- cgit v1.2.1 From 4f2f91a34f2e66a4511ebf0a650f379bd1c0e41f Mon Sep 17 00:00:00 2001 From: Yuang Li Date: Tue, 6 Sep 2022 15:45:07 +0100 Subject: fix shallow array search --- src/libgit2/transports/smart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart.c b/src/libgit2/transports/smart.c index b0925c8bb..04ee7e740 100644 --- a/src/libgit2/transports/smart.c +++ b/src/libgit2/transports/smart.c @@ -497,7 +497,7 @@ 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) { + 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); -- cgit v1.2.1 From 1cc2979a71ba042c20ea3e18484d4a50c4fdf10d Mon Sep 17 00:00:00 2001 From: lmcglash Date: Fri, 10 Mar 2023 08:56:49 +0000 Subject: Fix merge error --- src/libgit2/commit.c | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c index 017c60303..a7d831115 100644 --- a/src/libgit2/commit.c +++ b/src/libgit2/commit.c @@ -517,6 +517,18 @@ int git_commit__parse( return git_commit__parse_ext(commit, odb_obj, &parse_options); } +int git_commit__parse_raw( + void *commit, + const char *data, + size_t size, + git_oid_t oid_type) +{ + git_commit__parse_options parse_options = {0}; + parse_options.oid_type = oid_type; + + return commit_parse(commit, data, size, &parse_options); +} + static int assign_commit_parents_from_graft(git_commit *commit, git_commit_graft *graft) { size_t idx; git_oid *oid; @@ -533,14 +545,17 @@ static int assign_commit_parents_from_graft(git_commit *commit, git_commit_graft return 0; } -int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags) +int git_commit__parse_ext( + git_commit *commit, + git_odb_object *odb_obj, + git_commit__parse_options *parse_opts) { git_repository *repo = git_object_owner((git_object *)commit); git_commit_graft *graft; int error; if ((error = commit_parse(commit, git_odb_object_data(odb_obj), - git_odb_object_size(odb_obj), flags)) < 0) + git_odb_object_size(odb_obj), parse_opts)) < 0) return error; if (!git_shallow__enabled) @@ -554,30 +569,6 @@ int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned return assign_commit_parents_from_graft(commit, graft); } -int git_commit__parse_raw( - void *commit, - const char *data, - size_t size, - git_oid_t oid_type) -{ - git_commit__parse_options parse_options = {0}; - parse_options.oid_type = oid_type; - - return commit_parse(commit, data, size, &parse_options); -} - -int git_commit__parse_ext( - git_commit *commit, - git_odb_object *odb_obj, - git_commit__parse_options *parse_opts) -{ - return commit_parse( - commit, - git_odb_object_data(odb_obj), - git_odb_object_size(odb_obj), - parse_opts); -} - #define GIT_COMMIT_GETTER(_rvalue, _name, _return, _invalid) \ _rvalue git_commit_##_name(const git_commit *commit) \ {\ -- cgit v1.2.1 From 2da3e8c16629cee9736965556a50dc7502e1dec7 Mon Sep 17 00:00:00 2001 From: lmcglash Date: Fri, 10 Mar 2023 09:06:26 +0000 Subject: Remove stray comma --- src/libgit2/transports/smart.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart.h b/src/libgit2/transports/smart.h index 15b6c9a0a..8e06d03ef 100644 --- a/src/libgit2/transports/smart.h +++ b/src/libgit2/transports/smart.h @@ -54,7 +54,7 @@ typedef enum { GIT_PKT_NG, GIT_PKT_UNPACK, GIT_PKT_SHALLOW, - GIT_PKT_UNSHALLOW, + GIT_PKT_UNSHALLOW } git_pkt_type; /* Used for multi_ack and multi_ack_detailed */ @@ -144,7 +144,7 @@ typedef struct transport_smart_caps { thin_pack:1, want_tip_sha1:1, want_reachable_sha1:1, - shallow:1; + shallow:1; char *object_format; char *agent; } transport_smart_caps; -- cgit v1.2.1 From 79ed94e0f86daae2d839f89789952f0e99eef32a Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Fri, 10 Mar 2023 09:30:29 +0000 Subject: Apply suggestions from code review Co-authored-by: Qix --- src/libgit2/transports/smart_protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c index 2ec390101..c37c3cc8d 100644 --- a/src/libgit2/transports/smart_protocol.c +++ b/src/libgit2/transports/smart_protocol.c @@ -359,7 +359,7 @@ static int cap_not_sup_err(const char *cap_name) /* Disables server capabilities we're not interested in */ static int setup_caps(transport_smart_caps *caps, const git_fetch_negotiation *wants) { - if (wants->depth) { + if (wants->depth > 0) { if (!caps->shallow) return cap_not_sup_err(GIT_CAP_SHALLOW); } else { -- cgit v1.2.1 From 5b711335603b6d6abe6ae9bf09f570ada66232ef Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Fri, 10 Mar 2023 09:32:33 +0000 Subject: Update src/libgit2/fetch.c Co-authored-by: Qix --- src/libgit2/fetch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index 3a574e857..6bf16bc0f 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -195,7 +195,7 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) */ remote->nego.refs = (const git_remote_head * const *)remote->refs.contents; remote->nego.count = remote->refs.length; - remote->nego.shallow_roots = git__malloc(sizeof(git_shallowarray)); + remote->nego.shallow_roots = git__malloc(sizeof(*remote->nego.shallow_roots)); git_array_init(remote->nego.shallow_roots->array); -- cgit v1.2.1 From dd15c615bde54eb02c5cec17257a83dcd8528371 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Apr 2023 23:19:59 +0100 Subject: shallow: remove feature flag The opt mechanism isn't _really_ meant to be for feature flags, and it's weird to feature flag shallow / unshallow at all. --- src/libgit2/commit.c | 5 +---- src/libgit2/grafts.c | 6 ++---- src/libgit2/grafts.h | 2 -- src/libgit2/libgit2.c | 4 ---- src/libgit2/repository.c | 2 +- 5 files changed, 4 insertions(+), 15 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c index a7d831115..f7be73acf 100644 --- a/src/libgit2/commit.c +++ b/src/libgit2/commit.c @@ -553,14 +553,11 @@ int git_commit__parse_ext( git_repository *repo = git_object_owner((git_object *)commit); git_commit_graft *graft; int error; - + if ((error = commit_parse(commit, git_odb_object_data(odb_obj), git_odb_object_size(odb_obj), parse_opts)) < 0) return error; - if (!git_shallow__enabled) - return 0; - /* Perform necessary grafts */ if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) != 0 && git_grafts_get(&graft, repo->shallow_grafts, git_odb_object_id(odb_obj)) != 0) diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 7cbb1dd76..13c33aad0 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -12,8 +12,6 @@ #include "oidarray.h" #include "parse.h" -bool git_shallow__enabled = false; - struct git_grafts { /* Map of `git_commit_graft`s */ git_oidmap *commits; @@ -97,13 +95,13 @@ int git_grafts_refresh(git_grafts *grafts) if (!grafts->path) return 0; - if ((error = git_futils_readbuffer_updated(&contents, grafts->path, + if ((error = git_futils_readbuffer_updated(&contents, grafts->path, (grafts->path_checksum).id, &updated)) < 0) { if (error == GIT_ENOTFOUND) { git_grafts_clear(grafts); error = 0; } - + goto cleanup; } diff --git a/src/libgit2/grafts.h b/src/libgit2/grafts.h index 4139438bb..fc61468f5 100644 --- a/src/libgit2/grafts.h +++ b/src/libgit2/grafts.h @@ -19,8 +19,6 @@ typedef struct { typedef struct git_grafts git_grafts; -extern bool git_shallow__enabled; - int git_grafts_new(git_grafts **out); int git_grafts_from_file(git_grafts **out, const char *path); void git_grafts_free(git_grafts *grafts); diff --git a/src/libgit2/libgit2.c b/src/libgit2/libgit2.c index c5a9287fb..178880c9e 100644 --- a/src/libgit2/libgit2.c +++ b/src/libgit2/libgit2.c @@ -436,10 +436,6 @@ int git_libgit2_opts(int key, ...) error = git_sysdir_set(GIT_SYSDIR_HOME, va_arg(ap, const char *)); break; - case GIT_OPT_ENABLE_SHALLOW: - git_shallow__enabled = (va_arg(ap, int) != 0); - break; - default: git_error_set(GIT_ERROR_INVALID, "invalid option key"); error = -1; diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 1e356c84e..99982b724 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -1099,7 +1099,7 @@ int git_repository_open_ext( if (error < 0) goto cleanup; - if (git_shallow__enabled && (error = load_grafts(repo)) < 0) + if ((error = load_grafts(repo)) < 0) goto cleanup; if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) { -- cgit v1.2.1 From 48273490e7ccfaa56b784c69cb488111bd06f357 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Apr 2023 23:42:41 +0100 Subject: shallow: use GIT_ASSERT (not assert) --- src/libgit2/grafts.c | 13 +++++++------ src/libgit2/repository.c | 11 ++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 13c33aad0..1bfdc500e 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -75,7 +75,8 @@ void git_grafts_clear(git_grafts *grafts) { git_commit_graft *graft; - assert(grafts); + if (!grafts) + return; git_oidmap_foreach_value(grafts->commits, graft, { git__free(graft->parents.ptr); @@ -90,7 +91,7 @@ int git_grafts_refresh(git_grafts *grafts) git_str contents = GIT_STR_INIT; int error, updated = 0; - assert(grafts); + GIT_ASSERT_ARG(grafts); if (!grafts->path) return 0; @@ -168,7 +169,7 @@ int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t paren int error; size_t i; - assert(grafts && oid); + GIT_ASSERT_ARG(grafts && oid); graft = git__calloc(1, sizeof(*graft)); GIT_ERROR_CHECK_ALLOC(graft); @@ -200,7 +201,7 @@ int git_grafts_remove(git_grafts *grafts, const git_oid *oid) git_commit_graft *graft; int error; - assert(grafts && oid); + GIT_ASSERT_ARG(grafts && oid); if ((graft = git_oidmap_get(grafts->commits, oid)) == NULL) return GIT_ENOTFOUND; @@ -216,7 +217,7 @@ int git_grafts_remove(git_grafts *grafts, const git_oid *oid) int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid) { - assert(out && grafts && oid); + GIT_ASSERT_ARG(out && grafts && oid); if ((*out = git_oidmap_get(grafts->commits, oid)) == NULL) return GIT_ENOTFOUND; return 0; @@ -228,7 +229,7 @@ int git_grafts_get_oids(git_array_oid_t *out, git_grafts *grafts) size_t i = 0; int error; - assert(out && grafts); + GIT_ASSERT_ARG(out && grafts); while ((error = git_oidmap_iterate(NULL, grafts->commits, &i, &oid)) == 0) { git_oid *cpy = git_array_alloc(*out); diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 99982b724..3b6ecae24 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -1613,14 +1613,16 @@ int git_repository_set_index(git_repository *repo, git_index *index) int git_repository_grafts__weakptr(git_grafts **out, git_repository *repo) { - assert(out && repo && repo->grafts); + GIT_ASSERT_ARG(out && repo); + GIT_ASSERT(repo->grafts); *out = repo->grafts; return 0; } int git_repository_shallow_grafts__weakptr(git_grafts **out, git_repository *repo) { - assert(out && repo && repo->shallow_grafts); + GIT_ASSERT_ARG(out && repo); + GIT_ASSERT(repo->shallow_grafts); *out = repo->shallow_grafts; return 0; } @@ -3672,7 +3674,7 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro git_oid *oid; int filebuf_hash, error = 0; - assert(repo); + GIT_ASSERT_ARG(repo); filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(GIT_OID_SHA1)); GIT_ASSERT(filebuf_hash); @@ -3695,9 +3697,8 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro goto on_error; } - if (git_array_size(roots) == 0) { + if (git_array_size(roots) == 0) remove(path.ptr); - } on_error: git_str_dispose(&path); -- cgit v1.2.1 From 3853ba8de64a0e774c6e73aacb5831707f841621 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Apr 2023 23:55:44 +0100 Subject: smart: validate shallow/unshallow pkts --- src/libgit2/transports/smart_pkt.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index ec9764a87..e8c87cb8d 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -444,11 +444,15 @@ static int shallow_pkt(git_pkt **out, const char *line, size_t len) GIT_ERROR_CHECK_ALLOC(pkt); pkt->type = GIT_PKT_SHALLOW; - line += 7; - len -= 7; + + if (git__prefixncmp(line, len, "shallow ")) + goto out_err; + + line += 8; + len -= 8; if (len >= GIT_OID_SHA1_HEXSIZE) { - git_oid__fromstr(&pkt->oid, line + 1, GIT_OID_SHA1); + git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1); line += GIT_OID_SHA1_HEXSIZE + 1; len -= GIT_OID_SHA1_HEXSIZE + 1; } @@ -456,6 +460,11 @@ static int shallow_pkt(git_pkt **out, const char *line, size_t len) *out = (git_pkt *) pkt; return 0; + +out_err: + git_error_set(GIT_ERROR_NET, "invalid packet line"); + git__free(pkt); + return -1; } static int unshallow_pkt(git_pkt **out, const char *line, size_t len) @@ -466,11 +475,15 @@ static int unshallow_pkt(git_pkt **out, const char *line, size_t len) GIT_ERROR_CHECK_ALLOC(pkt); pkt->type = GIT_PKT_UNSHALLOW; - line += 9; - len -= 9; + + if (git__prefixncmp(line, len, "unshallow ")) + goto out_err; + + line += 10; + len -= 10; if (len >= GIT_OID_SHA1_HEXSIZE) { - git_oid__fromstr(&pkt->oid, line + 1, GIT_OID_SHA1); + git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1); line += GIT_OID_SHA1_HEXSIZE + 1; len -= GIT_OID_SHA1_HEXSIZE + 1; } @@ -478,6 +491,11 @@ static int unshallow_pkt(git_pkt **out, const char *line, size_t len) *out = (git_pkt *) pkt; return 0; + +out_err: + git_error_set(GIT_ERROR_NET, "invalid packet line"); + git__free(pkt); + return -1; } static int parse_len(size_t *out, const char *line, size_t linelen) -- cgit v1.2.1 From 72139ef289383dafeea355ace222359c48d98563 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 23 Apr 2023 00:07:06 +0100 Subject: shallow: don't assume SHA1 --- src/libgit2/repository.c | 6 ++-- src/libgit2/transports/smart_pkt.c | 66 ++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 26 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 3b6ecae24..a60fb23fa 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3670,13 +3670,14 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro { git_filebuf file = GIT_FILEBUF_INIT; git_str path = GIT_STR_INIT; + char oid_str[GIT_OID_MAX_HEXSIZE + 1]; size_t idx; git_oid *oid; int filebuf_hash, error = 0; GIT_ASSERT_ARG(repo); - filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(GIT_OID_SHA1)); + filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(repo->oid_type)); GIT_ASSERT(filebuf_hash); if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0) @@ -3686,7 +3687,8 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro goto on_error; git_array_foreach(roots, idx, oid) { - git_filebuf_write(&file, git_oid_tostr_s(oid), GIT_OID_SHA1_HEXSIZE); + git_oid_tostr(oid_str, sizeof(oid_str), oid); + git_filebuf_write(&file, oid_str, git_oid_hexsize(repo->oid_type)); git_filebuf_write(&file, "\n", 1); } diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index e8c87cb8d..3199c18f0 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -44,9 +44,14 @@ static int flush_pkt(git_pkt **out) } /* the rest of the line will be useful for multi_ack and multi_ack_detailed */ -static int ack_pkt(git_pkt **out, const char *line, size_t len) +static int ack_pkt( + git_pkt **out, + const char *line, + size_t len, + git_pkt_parse_data *data) { git_pkt_ack *pkt; + size_t oid_hexsize = git_oid_hexsize(data->oid_type); pkt = git__calloc(1, sizeof(git_pkt_ack)); GIT_ERROR_CHECK_ALLOC(pkt); @@ -57,11 +62,11 @@ static int ack_pkt(git_pkt **out, const char *line, size_t len) line += 4; len -= 4; - if (len < GIT_OID_SHA1_HEXSIZE || - git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1) < 0) + if (len < oid_hexsize || + git_oid__fromstr(&pkt->oid, line, data->oid_type) < 0) goto out_err; - line += GIT_OID_SHA1_HEXSIZE; - len -= GIT_OID_SHA1_HEXSIZE; + line += oid_hexsize; + len -= oid_hexsize; if (len && line[0] == ' ') { line++; @@ -436,9 +441,14 @@ static int unpack_pkt(git_pkt **out, const char *line, size_t len) return 0; } -static int shallow_pkt(git_pkt **out, const char *line, size_t len) +static int shallow_pkt( + git_pkt **out, + const char *line, + size_t len, + git_pkt_parse_data *data) { git_pkt_shallow *pkt; + size_t oid_hexsize = git_oid_hexsize(data->oid_type); pkt = git__calloc(1, sizeof(git_pkt_shallow)); GIT_ERROR_CHECK_ALLOC(pkt); @@ -451,13 +461,14 @@ static int shallow_pkt(git_pkt **out, const char *line, size_t len) line += 8; len -= 8; - if (len >= GIT_OID_SHA1_HEXSIZE) { - git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1); - line += GIT_OID_SHA1_HEXSIZE + 1; - len -= GIT_OID_SHA1_HEXSIZE + 1; - } + if (len != oid_hexsize) + goto out_err; - *out = (git_pkt *) pkt; + git_oid__fromstr(&pkt->oid, line, data->oid_type); + line += oid_hexsize + 1; + len -= oid_hexsize + 1; + + *out = (git_pkt *)pkt; return 0; @@ -467,9 +478,14 @@ out_err: return -1; } -static int unshallow_pkt(git_pkt **out, const char *line, size_t len) +static int unshallow_pkt( + git_pkt **out, + const char *line, + size_t len, + git_pkt_parse_data *data) { git_pkt_shallow *pkt; + size_t oid_hexsize = git_oid_hexsize(data->oid_type); pkt = git__calloc(1, sizeof(git_pkt_shallow)); GIT_ERROR_CHECK_ALLOC(pkt); @@ -482,11 +498,12 @@ static int unshallow_pkt(git_pkt **out, const char *line, size_t len) line += 10; len -= 10; - if (len >= GIT_OID_SHA1_HEXSIZE) { - git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1); - line += GIT_OID_SHA1_HEXSIZE + 1; - len -= GIT_OID_SHA1_HEXSIZE + 1; - } + if (len != oid_hexsize) + goto out_err; + + git_oid__fromstr(&pkt->oid, line, data->oid_type); + line += oid_hexsize + 1; + len -= oid_hexsize + 1; *out = (git_pkt *) pkt; @@ -615,7 +632,7 @@ int git_pkt_parse_line( else if (*line == GIT_SIDE_BAND_ERROR) error = sideband_error_pkt(pkt, line, len); else if (!git__prefixncmp(line, len, "ACK")) - error = ack_pkt(pkt, line, len); + error = ack_pkt(pkt, line, len, data); else if (!git__prefixncmp(line, len, "NAK")) error = nak_pkt(pkt); else if (!git__prefixncmp(line, len, "ERR")) @@ -629,9 +646,9 @@ int git_pkt_parse_line( else if (!git__prefixncmp(line, len, "unpack")) error = unpack_pkt(pkt, line, len); else if (!git__prefixcmp(line, "shallow")) - error = shallow_pkt(pkt, line, len); + error = shallow_pkt(pkt, line, len, data); else if (!git__prefixcmp(line, "unshallow")) - error = unshallow_pkt(pkt, line, len); + error = unshallow_pkt(pkt, line, len, data); else error = ref_pkt(pkt, line, len, data); @@ -788,12 +805,13 @@ int git_pkt_buffer_wants( /* Tell the server about our shallow objects */ for (i = 0; i < git_shallowarray_count(wants->shallow_roots); i++) { - char oid[GIT_OID_SHA1_HEXSIZE]; + char oid[GIT_OID_MAX_HEXSIZE + 1]; git_str shallow_buf = GIT_STR_INIT; - git_oid_fmt(oid, git_shallowarray_get(wants->shallow_roots, i)); + git_oid_tostr(oid, GIT_OID_MAX_HEXSIZE + 1, + git_shallowarray_get(wants->shallow_roots, i)); git_str_puts(&shallow_buf, "shallow "); - git_str_put(&shallow_buf, oid, GIT_OID_SHA1_HEXSIZE); + git_str_puts(&shallow_buf, oid); git_str_putc(&shallow_buf, '\n'); git_str_printf(buf, "%04x%s", (unsigned int)git_str_len(&shallow_buf) + 4, git_str_cstr(&shallow_buf)); -- cgit v1.2.1 From d69c7a72386c9e01f4b0c8945724f870bf9aa4f6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 24 Apr 2023 11:43:03 +0100 Subject: transport: transports understand oid type Teach the smart transport more about oid types, instead of assuming SHA1. --- src/libgit2/transports/smart_pkt.c | 6 ++++++ src/libgit2/transports/smart_protocol.c | 26 ++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index 3199c18f0..f2c9eea8e 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -53,6 +53,8 @@ static int ack_pkt( git_pkt_ack *pkt; size_t oid_hexsize = git_oid_hexsize(data->oid_type); + GIT_ASSERT(data && data->oid_type); + pkt = git__calloc(1, sizeof(git_pkt_ack)); GIT_ERROR_CHECK_ALLOC(pkt); pkt->type = GIT_PKT_ACK; @@ -450,6 +452,8 @@ static int shallow_pkt( git_pkt_shallow *pkt; size_t oid_hexsize = git_oid_hexsize(data->oid_type); + GIT_ASSERT(data && data->oid_type); + pkt = git__calloc(1, sizeof(git_pkt_shallow)); GIT_ERROR_CHECK_ALLOC(pkt); @@ -487,6 +491,8 @@ static int unshallow_pkt( git_pkt_shallow *pkt; size_t oid_hexsize = git_oid_hexsize(data->oid_type); + GIT_ASSERT(data && data->oid_type); + pkt = git__calloc(1, sizeof(git_pkt_shallow)); GIT_ERROR_CHECK_ALLOC(pkt); diff --git a/src/libgit2/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c index c37c3cc8d..eb2bc5be4 100644 --- a/src/libgit2/transports/smart_protocol.c +++ b/src/libgit2/transports/smart_protocol.c @@ -256,13 +256,20 @@ int git_smart__detect_caps( return 0; } -static int recv_pkt(git_pkt **out_pkt, git_pkt_type *out_type, gitno_buffer *buf) +static int recv_pkt( + git_pkt **out_pkt, + git_pkt_type *out_type, + transport_smart *t, + gitno_buffer *buf) { const char *ptr = buf->data, *line_end = ptr; git_pkt *pkt = NULL; git_pkt_parse_data pkt_parse_data = { 0 }; int error = 0, ret; + pkt_parse_data.oid_type = t->owner->repo->oid_type; + pkt_parse_data.seen_capabilities = 1; + do { if (buf->offset > 0) error = git_pkt_parse_line(&pkt, &line_end, ptr, buf->offset, &pkt_parse_data); @@ -303,7 +310,7 @@ static int store_common(transport_smart *t) int error; do { - if ((error = recv_pkt(&pkt, NULL, buf)) < 0) + if ((error = recv_pkt(&pkt, NULL, t, buf)) < 0) return error; if (pkt->type != GIT_PKT_ACK) { @@ -320,7 +327,7 @@ static int store_common(transport_smart *t) return 0; } -static int wait_while_ack(gitno_buffer *buf) +static int wait_while_ack(transport_smart *t, gitno_buffer *buf) { int error; git_pkt *pkt = NULL; @@ -329,7 +336,7 @@ static int wait_while_ack(gitno_buffer *buf) while (1) { git_pkt_free(pkt); - if ((error = recv_pkt(&pkt, NULL, buf)) < 0) + if ((error = recv_pkt(&pkt, NULL, t, buf)) < 0) return error; if (pkt->type == GIT_PKT_NAK) @@ -400,8 +407,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c if ((error = git_smart__negotiation_step(&t->parent, data.ptr, data.size)) < 0) goto on_error; - while ((error = recv_pkt((git_pkt **)&pkt, NULL, buf)) == 0) { - + while ((error = recv_pkt((git_pkt **)&pkt, NULL, t, buf)) == 0) { if (pkt->type == GIT_PKT_SHALLOW) { git_shallowarray_add(wants->shallow_roots, &pkt->oid); } else if (pkt->type == GIT_PKT_UNSHALLOW) { @@ -463,7 +469,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c if ((error = store_common(t)) < 0) goto on_error; } else { - if ((error = recv_pkt(NULL, &pkt_type, buf)) < 0) + if ((error = recv_pkt(NULL, &pkt_type, t, buf)) < 0) goto on_error; if (pkt_type == GIT_PKT_ACK) { @@ -535,7 +541,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c /* Now let's eat up whatever the server gives us */ if (!t->caps.multi_ack && !t->caps.multi_ack_detailed) { - if ((error = recv_pkt(NULL, &pkt_type, buf)) < 0) + if ((error = recv_pkt(NULL, &pkt_type, t, buf)) < 0) return error; if (pkt_type != GIT_PKT_ACK && pkt_type != GIT_PKT_NAK) { @@ -543,7 +549,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c return -1; } } else { - error = wait_while_ack(buf); + error = wait_while_ack(t, buf); } return error; @@ -659,7 +665,7 @@ int git_smart__download_pack( goto done; } - if ((error = recv_pkt(&pkt, NULL, buf)) >= 0) { + if ((error = recv_pkt(&pkt, NULL, t, buf)) >= 0) { /* Check cancellation after network call */ if (t->cancelled.val) { git_error_clear(); -- cgit v1.2.1 From 8f7fc2ee505a0abe2186270a79b287e321c748c4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 24 Apr 2023 11:16:47 +0100 Subject: shallow: avoid unnecessary pkt free Looks like a double-free here. --- src/libgit2/transports/smart_protocol.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c index eb2bc5be4..6167a8074 100644 --- a/src/libgit2/transports/smart_protocol.c +++ b/src/libgit2/transports/smart_protocol.c @@ -408,26 +408,28 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c goto on_error; while ((error = recv_pkt((git_pkt **)&pkt, NULL, t, buf)) == 0) { + bool complete = false; + if (pkt->type == GIT_PKT_SHALLOW) { git_shallowarray_add(wants->shallow_roots, &pkt->oid); } else if (pkt->type == GIT_PKT_UNSHALLOW) { git_shallowarray_remove(wants->shallow_roots, &pkt->oid); } else if (pkt->type == GIT_PKT_FLUSH) { /* Server is done, stop processing shallow oids */ - break; + complete = true; } else { - git_error_set(GIT_ERROR_NET, "Unexpected pkt type"); - goto on_error; + git_error_set(GIT_ERROR_NET, "unexpected packet type"); + error = -1; } git_pkt_free((git_pkt *) pkt); - } - git_pkt_free((git_pkt *) pkt); + if (complete || error < 0) + break; + } - if (error < 0) { + if (error < 0) goto on_error; - } } /* * Our support for ACK extensions is simply to parse them. On -- cgit v1.2.1 From 6a02b459ab1d9ca6eaeda96cce94ba5ce6f8eaea Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 24 Apr 2023 12:15:11 +0100 Subject: futils: use SHA256 for checksums always Use SHA256 for file checksums. SHA1 makes no sense as a default in 2023. Given that we're just looking at a file checksum to see if it's changed, this does not need to take repository's OID type into account or otherwise be configurable. --- src/libgit2/grafts.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 1bfdc500e..ef314550d 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -18,7 +18,7 @@ struct git_grafts { /* File backing the graft. NULL if it's an in-memory graft */ char *path; - git_oid path_checksum; + unsigned char path_checksum[GIT_HASH_SHA256_SIZE]; }; int git_grafts_new(git_grafts **out) @@ -97,7 +97,8 @@ int git_grafts_refresh(git_grafts *grafts) return 0; if ((error = git_futils_readbuffer_updated(&contents, grafts->path, - (grafts->path_checksum).id, &updated)) < 0) { + grafts->path_checksum, &updated)) < 0) { + if (error == GIT_ENOTFOUND) { git_grafts_clear(grafts); error = 0; -- cgit v1.2.1 From 69592bde1f2789162b215b612df7c8a13956b722 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 24 Apr 2023 13:09:15 +0100 Subject: grafts: use `git_parse` to parse object IDs Don't mix parsing by hand and using `git_parse` to parse. --- src/libgit2/grafts.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index ef314550d..d46fc12c1 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -119,7 +119,7 @@ cleanup: return error; } -int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen) +int git_grafts_parse(git_grafts *grafts, const char *buf, size_t len) { git_array_oid_t parents = GIT_ARRAY_INIT; git_parse_ctx parser; @@ -127,29 +127,26 @@ int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen) git_grafts_clear(grafts); - if ((error = git_parse_ctx_init(&parser, content, contentlen)) < 0) + if ((error = git_parse_ctx_init(&parser, buf, len)) < 0) goto error; for (; parser.remain_len; git_parse_advance_line(&parser)) { - const char *line_start = parser.line, *line_end = parser.line + parser.line_len; git_oid graft_oid; - if ((error = git_oid__fromstrn(&graft_oid, line_start, GIT_OID_SHA1_HEXSIZE, GIT_OID_SHA1)) < 0) { + if ((error = git_parse_advance_oid(&graft_oid, &parser, GIT_OID_SHA1)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid graft OID at line %" PRIuZ, parser.line_num); goto error; } - line_start += GIT_OID_SHA1_HEXSIZE; - while (line_start < line_end && *line_start == ' ') { + while (parser.line_len && git_parse_advance_expected(&parser, "\n", 1) != 0) { git_oid *id = git_array_alloc(parents); GIT_ERROR_CHECK_ALLOC(id); - if ((error = git_oid__fromstrn(id, ++line_start, GIT_OID_SHA1_HEXSIZE, GIT_OID_SHA1)) < 0) { + if ((error = git_parse_advance_expected(&parser, " ", 1)) < 0 || + (error = git_parse_advance_oid(id, &parser, GIT_OID_SHA1)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid parent OID at line %" PRIuZ, parser.line_num); goto error; } - - line_start += GIT_OID_SHA1_HEXSIZE; } if ((error = git_grafts_add(grafts, &graft_oid, parents)) < 0) @@ -186,6 +183,7 @@ int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t paren if ((error = git_grafts_remove(grafts, &graft->oid)) < 0 && error != GIT_ENOTFOUND) goto cleanup; + if ((error = git_oidmap_set(grafts->commits, &graft->oid, graft)) < 0) goto cleanup; -- cgit v1.2.1 From 7d7f3059decbd6b4730bfd09da54726c1b3ed8ea Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 24 Apr 2023 13:32:43 +0100 Subject: grafts: handle SHA256 graft files --- src/libgit2/grafts.c | 22 +++++++++++++++++----- src/libgit2/grafts.h | 6 +++--- src/libgit2/repository.c | 4 ++-- 3 files changed, 22 insertions(+), 10 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index d46fc12c1..00de03e8b 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -16,15 +16,20 @@ struct git_grafts { /* Map of `git_commit_graft`s */ git_oidmap *commits; + /* Type of object IDs */ + git_oid_t oid_type; + /* File backing the graft. NULL if it's an in-memory graft */ char *path; unsigned char path_checksum[GIT_HASH_SHA256_SIZE]; }; -int git_grafts_new(git_grafts **out) +int git_grafts_new(git_grafts **out, git_oid_t oid_type) { git_grafts *grafts; + GIT_ASSERT_ARG(out && oid_type); + grafts = git__calloc(1, sizeof(*grafts)); GIT_ERROR_CHECK_ALLOC(grafts); @@ -33,19 +38,26 @@ int git_grafts_new(git_grafts **out) return -1; } + grafts->oid_type = oid_type; + *out = grafts; return 0; } -int git_grafts_from_file(git_grafts **out, const char *path) +int git_grafts_from_file( + git_grafts **out, + const char *path, + git_oid_t oid_type) { git_grafts *grafts = NULL; int error; + GIT_ASSERT_ARG(path && oid_type); + if (*out) return git_grafts_refresh(*out); - if ((error = git_grafts_new(&grafts)) < 0) + if ((error = git_grafts_new(&grafts, oid_type)) < 0) goto error; grafts->path = git__strdup(path); @@ -133,7 +145,7 @@ int git_grafts_parse(git_grafts *grafts, const char *buf, size_t len) for (; parser.remain_len; git_parse_advance_line(&parser)) { git_oid graft_oid; - if ((error = git_parse_advance_oid(&graft_oid, &parser, GIT_OID_SHA1)) < 0) { + if ((error = git_parse_advance_oid(&graft_oid, &parser, grafts->oid_type)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid graft OID at line %" PRIuZ, parser.line_num); goto error; } @@ -143,7 +155,7 @@ int git_grafts_parse(git_grafts *grafts, const char *buf, size_t len) GIT_ERROR_CHECK_ALLOC(id); if ((error = git_parse_advance_expected(&parser, " ", 1)) < 0 || - (error = git_parse_advance_oid(id, &parser, GIT_OID_SHA1)) < 0) { + (error = git_parse_advance_oid(id, &parser, grafts->oid_type)) < 0) { git_error_set(GIT_ERROR_GRAFTS, "invalid parent OID at line %" PRIuZ, parser.line_num); goto error; } diff --git a/src/libgit2/grafts.h b/src/libgit2/grafts.h index fc61468f5..0c0e9cecb 100644 --- a/src/libgit2/grafts.h +++ b/src/libgit2/grafts.h @@ -19,13 +19,13 @@ typedef struct { typedef struct git_grafts git_grafts; -int git_grafts_new(git_grafts **out); -int git_grafts_from_file(git_grafts **out, const char *path); +int git_grafts_new(git_grafts **out, git_oid_t oid_type); +int git_grafts_from_file(git_grafts **out, const char *path, git_oid_t oid_type); void git_grafts_free(git_grafts *grafts); void git_grafts_clear(git_grafts *grafts); int git_grafts_refresh(git_grafts *grafts); -int git_grafts_parse(git_grafts *grafts, const char *content, size_t contentlen); +int git_grafts_parse(git_grafts *grafts, const char *buf, size_t len); int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t parents); int git_grafts_remove(git_grafts *grafts, const git_oid *oid); int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid); diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index a60fb23fa..5778a86f7 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -852,13 +852,13 @@ static int load_grafts(git_repository *repo) if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || (error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 || - (error = git_grafts_from_file(&repo->grafts, path.ptr)) < 0) + (error = git_grafts_from_file(&repo->grafts, path.ptr, repo->oid_type)) < 0) goto error; git_str_clear(&path); if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0 || - (error = git_grafts_from_file(&repo->shallow_grafts, path.ptr)) < 0) + (error = git_grafts_from_file(&repo->shallow_grafts, path.ptr, repo->oid_type)) < 0) goto error; error: -- cgit v1.2.1 From 3388f5ba1b821e9683d21ca41c34ed752d2db222 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 25 Apr 2023 09:31:34 +0100 Subject: shallow: don't default to -1 for depth Depth of `0` should indicate full depth. Disallow negative values (they may have a future meaning) and use `0` as the default. --- src/libgit2/clone.c | 2 +- src/libgit2/fetch.c | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/clone.c b/src/libgit2/clone.c index 43341a493..fca0ca0cc 100644 --- a/src/libgit2/clone.c +++ b/src/libgit2/clone.c @@ -421,7 +421,7 @@ static int clone_into( memcpy(&fetch_opts, opts, sizeof(git_fetch_options)); fetch_opts.update_fetchhead = 0; - if (opts->depth <= 0) + if (!opts->depth) fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL; if ((error = git_remote_connect_options__from_fetch_opts(&connect_opts, remote, &fetch_opts)) < 0) diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index d66892ca0..86b650a60 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -172,10 +172,12 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) remote->need_pack = 0; - if (!opts) - remote->nego.depth = -1; - else + if (opts) { + GIT_ASSERT_ARG(opts->unshallow == 0 || opts->depth == 0); + GIT_ASSERT_ARG(opts->depth >= 0); + remote->nego.depth = opts->unshallow ? INT_MAX : opts->depth; + } if (filter_wants(remote, opts) < 0) return -1; @@ -184,11 +186,6 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) if (!remote->need_pack) return 0; - if (opts && 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. -- cgit v1.2.1 From 43db928895fa85e4ee104dc8757275400d5acc2a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 25 Apr 2023 10:48:33 +0100 Subject: grafts: make `from_file` be `open_or_refresh` The semantics of `from_file` are weird - it looks like a function that just opens a file, but it actually inspects the pointer, which is unexpected and could make things very crashy. Make an `open` function that just does an open, and move the magic to `open_or_refresh` whose name better indicates that it may do weird stuff. --- src/libgit2/grafts.c | 19 ++++++++++++++----- src/libgit2/grafts.h | 3 ++- src/libgit2/repository.c | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 00de03e8b..83f5b2ab4 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -44,7 +44,7 @@ int git_grafts_new(git_grafts **out, git_oid_t oid_type) return 0; } -int git_grafts_from_file( +int git_grafts_open( git_grafts **out, const char *path, git_oid_t oid_type) @@ -52,10 +52,7 @@ int git_grafts_from_file( git_grafts *grafts = NULL; int error; - GIT_ASSERT_ARG(path && oid_type); - - if (*out) - return git_grafts_refresh(*out); + GIT_ASSERT_ARG(out && path && oid_type); if ((error = git_grafts_new(&grafts, oid_type)) < 0) goto error; @@ -67,12 +64,24 @@ int git_grafts_from_file( goto error; *out = grafts; + error: if (error < 0) git_grafts_free(grafts); + return error; } +int git_grafts_open_or_refresh( + git_grafts **out, + const char *path, + git_oid_t oid_type) +{ + GIT_ASSERT_ARG(out && path && oid_type); + + return *out ? git_grafts_refresh(*out) : git_grafts_open(out, path, oid_type); +} + void git_grafts_free(git_grafts *grafts) { if (!grafts) diff --git a/src/libgit2/grafts.h b/src/libgit2/grafts.h index 0c0e9cecb..0d561fc25 100644 --- a/src/libgit2/grafts.h +++ b/src/libgit2/grafts.h @@ -20,7 +20,8 @@ typedef struct { typedef struct git_grafts git_grafts; int git_grafts_new(git_grafts **out, git_oid_t oid_type); -int git_grafts_from_file(git_grafts **out, const char *path, git_oid_t oid_type); +int git_grafts_open(git_grafts **out, const char *path, git_oid_t oid_type); +int git_grafts_open_or_refresh(git_grafts **out, const char *path, git_oid_t oid_type); void git_grafts_free(git_grafts *grafts); void git_grafts_clear(git_grafts *grafts); diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 5778a86f7..763b62375 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -852,13 +852,13 @@ static int load_grafts(git_repository *repo) if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || (error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 || - (error = git_grafts_from_file(&repo->grafts, path.ptr, repo->oid_type)) < 0) + (error = git_grafts_open_or_refresh(&repo->grafts, path.ptr, repo->oid_type)) < 0) goto error; git_str_clear(&path); if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0 || - (error = git_grafts_from_file(&repo->shallow_grafts, path.ptr, repo->oid_type)) < 0) + (error = git_grafts_open_or_refresh(&repo->shallow_grafts, path.ptr, repo->oid_type)) < 0) goto error; error: -- cgit v1.2.1 From 0a7e32b2326c02a91f9560dfd209e56ea9fb9d49 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 8 May 2023 10:07:11 +0100 Subject: oid: use an oid array instead of shallowarray Users should provide us an array of object ids; we don't need a separate type. And especially, we should not be mutating user-providing values. Instead, use `git_oid *` in the shallow code. --- src/libgit2/fetch.c | 29 ++++++++++------- src/libgit2/grafts.c | 16 +++++++--- src/libgit2/grafts.h | 2 +- src/libgit2/oidarray.c | 52 ++++++++++++++++++++++++++++-- src/libgit2/oidarray.h | 6 +++- src/libgit2/remote.c | 5 --- src/libgit2/repository.c | 20 +++++++----- src/libgit2/repository.h | 4 +-- src/libgit2/transports/local.c | 11 +++++++ src/libgit2/transports/smart.c | 49 ++--------------------------- src/libgit2/transports/smart.h | 7 ++--- src/libgit2/transports/smart_pkt.c | 13 ++++---- src/libgit2/transports/smart_protocol.c | 56 +++++++++++++++++++++++++++++---- 13 files changed, 171 insertions(+), 99 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index 86b650a60..b43425215 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. - However if we are unshallowing, we need to ask for it + However if we are unshallowing, we need to ask for it even though the head exists locally. */ if (remote->nego.depth != INT_MAX && git_odb_exists(odb, &head->oid)) head->local = 1; @@ -169,6 +169,7 @@ cleanup: int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) { git_transport *t = remote->transport; + int error; remote->need_pack = 0; @@ -191,33 +192,39 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) * 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.shallow_roots = git__malloc(sizeof(*remote->nego.shallow_roots)); - - git_array_init(remote->nego.shallow_roots->array); + remote->nego.refs_len = remote->refs.length; - git_repository__shallow_roots(&remote->nego.shallow_roots->array, remote->repo); + if (git_repository__shallow_roots(&remote->nego.shallow_roots, + &remote->nego.shallow_roots_len, + remote->repo) < 0) + return -1; - return t->negotiate_fetch(t, + error = t->negotiate_fetch(t, remote->repo, &remote->nego); + + git__free(remote->nego.shallow_roots); + + return error; } int git_fetch_download_pack(git_remote *remote) { + git_oidarray shallow_roots = { NULL }; git_transport *t = remote->transport; int error; if (!remote->need_pack) return 0; - if ((error = t->download_pack(t, remote->repo, &remote->stats)) != 0) + if ((error = t->download_pack(t, remote->repo, &remote->stats)) != 0 || + (error = t->shallow_roots(&shallow_roots, t)) != 0) return error; - if ((error = git_repository__shallow_roots_write(remote->repo, remote->nego.shallow_roots->array)) != 0) - return error; + error = git_repository__shallow_roots_write(remote->repo, &shallow_roots); - return 0; + git_oidarray_dispose(&shallow_roots); + return error; } int git_fetch_options_init(git_fetch_options *opts, unsigned int version) diff --git a/src/libgit2/grafts.c b/src/libgit2/grafts.c index 83f5b2ab4..1d9373a56 100644 --- a/src/libgit2/grafts.c +++ b/src/libgit2/grafts.c @@ -243,20 +243,26 @@ int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oi return 0; } -int git_grafts_get_oids(git_array_oid_t *out, git_grafts *grafts) +int git_grafts_oids(git_oid **out, size_t *out_len, git_grafts *grafts) { + git_array_oid_t array = GIT_ARRAY_INIT; const git_oid *oid; - size_t i = 0; - int error; + size_t existing, i = 0; GIT_ASSERT_ARG(out && grafts); - while ((error = git_oidmap_iterate(NULL, grafts->commits, &i, &oid)) == 0) { - git_oid *cpy = git_array_alloc(*out); + if ((existing = git_oidmap_size(grafts->commits)) > 0) + git_array_init_to_size(array, existing); + + while (git_oidmap_iterate(NULL, grafts->commits, &i, &oid) == 0) { + git_oid *cpy = git_array_alloc(array); GIT_ERROR_CHECK_ALLOC(cpy); git_oid_cpy(cpy, oid); } + *out = array.ptr; + *out_len = array.size; + return 0; } diff --git a/src/libgit2/grafts.h b/src/libgit2/grafts.h index 0d561fc25..394867fd6 100644 --- a/src/libgit2/grafts.h +++ b/src/libgit2/grafts.h @@ -30,7 +30,7 @@ int git_grafts_parse(git_grafts *grafts, const char *buf, size_t len); int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t parents); int git_grafts_remove(git_grafts *grafts, const git_oid *oid); int git_grafts_get(git_commit_graft **out, git_grafts *grafts, const git_oid *oid); -int git_grafts_get_oids(git_array_oid_t *out, git_grafts *grafts); +int git_grafts_oids(git_oid **out, size_t *out_len, git_grafts *grafts); size_t git_grafts_size(git_grafts *grafts); #endif diff --git a/src/libgit2/oidarray.c b/src/libgit2/oidarray.c index 583017c4e..37f67756a 100644 --- a/src/libgit2/oidarray.c +++ b/src/libgit2/oidarray.c @@ -15,10 +15,17 @@ void git_oidarray_dispose(git_oidarray *arr) git__free(arr->ids); } -void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array) +void git_oidarray__from_array(git_oidarray *out, const git_array_oid_t *array) { - arr->count = array->size; - arr->ids = array->ptr; + out->count = array->size; + out->ids = array->ptr; +} + +void git_oidarray__to_array(git_array_oid_t *out, const git_oidarray *array) +{ + out->ptr = array->ids; + out->size = array->count; + out->asize = array->count; } void git_oidarray__reverse(git_oidarray *arr) @@ -33,6 +40,45 @@ void git_oidarray__reverse(git_oidarray *arr) } } +int git_oidarray__add(git_array_oid_t *arr, git_oid *id) +{ + git_oid *add, *iter; + size_t i; + + git_array_foreach(*arr, i, iter) { + if (git_oid_cmp(iter, id) == 0) + return 0; + } + + if ((add = git_array_alloc(*arr)) == NULL) + return -1; + + git_oid_cpy(add, id); + return 0; +} + +bool git_oidarray__remove(git_array_oid_t *arr, git_oid *id) +{ + bool found = false; + size_t remain, i; + git_oid *iter; + + git_array_foreach(*arr, i, iter) { + if (git_oid_cmp(iter, id) == 0) { + arr->size--; + remain = arr->size - i; + + if (remain > 0) + memmove(&arr->ptr[i], &arr->ptr[i+1], remain * sizeof(git_oid)); + + found = true; + break; + } + } + + return found; +} + #ifndef GIT_DEPRECATE_HARD void git_oidarray_free(git_oidarray *arr) diff --git a/src/libgit2/oidarray.h b/src/libgit2/oidarray.h index eed3a1091..8f1543a32 100644 --- a/src/libgit2/oidarray.h +++ b/src/libgit2/oidarray.h @@ -15,6 +15,10 @@ typedef git_array_t(git_oid) git_array_oid_t; extern void git_oidarray__reverse(git_oidarray *arr); -extern void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array); +extern void git_oidarray__from_array(git_oidarray *out, const git_array_oid_t *array); +extern void git_oidarray__to_array(git_array_oid_t *out, const git_oidarray *array); + +int git_oidarray__add(git_array_oid_t *arr, git_oid *id); +bool git_oidarray__remove(git_array_oid_t *arr, git_oid *id); #endif diff --git a/src/libgit2/remote.c b/src/libgit2/remote.c index ef414209f..fee2a7f39 100644 --- a/src/libgit2/remote.c +++ b/src/libgit2/remote.c @@ -2167,11 +2167,6 @@ void git_remote_free(git_remote *remote) remote->transport = NULL; } - if (remote->nego.shallow_roots) { - git_array_clear(remote->nego.shallow_roots->array); - git__free(remote->nego.shallow_roots); - } - git_vector_free(&remote->refs); free_refspecs(&remote->refspecs); diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 763b62375..8fcc4e2ba 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -3651,7 +3651,11 @@ int git_repository_state_cleanup(git_repository *repo) return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files)); } -int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo) { +int git_repository__shallow_roots( + git_oid **out, + size_t *out_len, + git_repository *repo) +{ int error = 0; if (!repo->shallow_grafts && (error = load_grafts(repo)) < 0) @@ -3660,19 +3664,18 @@ int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo) { if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0) return error; - if ((error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) + if ((error = git_grafts_oids(out, out_len, repo->shallow_grafts)) < 0) return error; return 0; } -int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t roots) +int git_repository__shallow_roots_write(git_repository *repo, git_oidarray *roots) { git_filebuf file = GIT_FILEBUF_INIT; git_str path = GIT_STR_INIT; char oid_str[GIT_OID_MAX_HEXSIZE + 1]; - size_t idx; - git_oid *oid; + size_t i; int filebuf_hash, error = 0; GIT_ASSERT_ARG(repo); @@ -3686,8 +3689,8 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro if ((error = git_filebuf_open(&file, git_str_cstr(&path), filebuf_hash, 0666)) < 0) goto on_error; - git_array_foreach(roots, idx, oid) { - git_oid_tostr(oid_str, sizeof(oid_str), oid); + for (i = 0; i < roots->count; i++) { + git_oid_tostr(oid_str, sizeof(oid_str), &roots->ids[i]); git_filebuf_write(&file, oid_str, git_oid_hexsize(repo->oid_type)); git_filebuf_write(&file, "\n", 1); } @@ -3699,7 +3702,7 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro goto on_error; } - if (git_array_size(roots) == 0) + if (!roots->count) remove(path.ptr); on_error: @@ -3727,6 +3730,7 @@ int git_repository_is_shallow(git_repository *repo) if (error < 0) return error; + return st.st_size == 0 ? 0 : 1; } diff --git a/src/libgit2/repository.h b/src/libgit2/repository.h index d86b36271..8dc20324d 100644 --- a/src/libgit2/repository.h +++ b/src/libgit2/repository.h @@ -246,8 +246,8 @@ extern size_t git_repository__reserved_names_posix_len; bool git_repository__reserved_names( git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs); -int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo); -int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t roots); +int git_repository__shallow_roots(git_oid **out, size_t *out_len, git_repository *repo); +int git_repository__shallow_roots_write(git_repository *repo, git_oidarray *roots); /* * The default branch for the repository; the `init.defaultBranch` diff --git a/src/libgit2/transports/local.c b/src/libgit2/transports/local.c index f576682a7..64c21afbd 100644 --- a/src/libgit2/transports/local.c +++ b/src/libgit2/transports/local.c @@ -320,6 +320,16 @@ static int local_negotiate_fetch( return 0; } +static int local_shallow_roots( + git_oidarray *out, + git_transport *transport) +{ + GIT_UNUSED(out); + GIT_UNUSED(transport); + + return 0; +} + static int local_push_update_remote_ref( git_repository *remote_repo, const char *lref, @@ -745,6 +755,7 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param) t->parent.oid_type = local_oid_type; #endif t->parent.negotiate_fetch = local_negotiate_fetch; + t->parent.shallow_roots = local_shallow_roots; t->parent.download_pack = local_download_pack; t->parent.push = local_push; t->parent.close = local_close; diff --git a/src/libgit2/transports/smart.c b/src/libgit2/transports/smart.c index da6dca039..a56524bff 100644 --- a/src/libgit2/transports/smart.c +++ b/src/libgit2/transports/smart.c @@ -416,6 +416,8 @@ static void git_smart__free(git_transport *transport) git_remote_connect_options_dispose(&t->connect_opts); + git_array_dispose(t->shallow_roots); + git__free(t->caps.object_format); git__free(t->caps.agent); git__free(t); @@ -490,6 +492,7 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param) t->parent.close = git_smart__close; t->parent.free = git_smart__free; t->parent.negotiate_fetch = git_smart__negotiate_fetch; + t->parent.shallow_roots = git_smart__shallow_roots; t->parent.download_pack = git_smart__download_pack; t->parent.push = git_smart__push; t->parent.ls = git_smart__ls; @@ -517,49 +520,3 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param) *out = (git_transport *) t; return 0; } - -size_t git_shallowarray_count(git_shallowarray *array) -{ - return git_array_size(array->array); -} - -const git_oid * git_shallowarray_get(git_shallowarray *array, size_t idx) -{ - return git_array_get(array->array, 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_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; -} diff --git a/src/libgit2/transports/smart.h b/src/libgit2/transports/smart.h index 8e06d03ef..34e27ea8e 100644 --- a/src/libgit2/transports/smart.h +++ b/src/libgit2/transports/smart.h @@ -163,6 +163,7 @@ typedef struct { git_vector refs; git_vector heads; git_vector common; + git_array_oid_t shallow_roots; git_atomic32 cancelled; packetsize_cb packetsize_cb; void *packetsize_payload; @@ -183,6 +184,8 @@ int git_smart__negotiate_fetch( git_repository *repo, const git_fetch_negotiation *wants); +int git_smart__shallow_roots(git_oidarray *out, git_transport *transport); + int git_smart__download_pack( git_transport *transport, git_repository *repo, @@ -208,8 +211,4 @@ int git_pkt_buffer_wants(const git_fetch_negotiation *wants, transport_smart_cap int git_pkt_buffer_have(git_oid *oid, git_str *buf); void git_pkt_free(git_pkt *pkt); -struct git_shallowarray { - git_array_oid_t array; -}; - #endif diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index f2c9eea8e..9127ad5fe 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -770,7 +770,7 @@ int git_pkt_buffer_wants( size_t oid_hexsize, want_len, i = 0; #ifdef GIT_EXPERIMENTAL_SHA256 - oid_type = wants->count > 0 ? wants->refs[0]->oid.type : GIT_OID_SHA1; + oid_type = wants->refs_len > 0 ? wants->refs[0]->oid.type : GIT_OID_SHA1; #else oid_type = GIT_OID_SHA1; #endif @@ -781,7 +781,7 @@ int git_pkt_buffer_wants( oid_hexsize + 1 /* LF */; if (caps->common) { - for (; i < wants->count; ++i) { + for (; i < wants->refs_len; ++i) { head = wants->refs[i]; if (!head->local) break; @@ -793,7 +793,7 @@ int git_pkt_buffer_wants( i++; } - for (; i < wants->count; ++i) { + for (; i < wants->refs_len; ++i) { head = wants->refs[i]; if (head->local) @@ -810,12 +810,11 @@ int git_pkt_buffer_wants( } /* Tell the server about our shallow objects */ - for (i = 0; i < git_shallowarray_count(wants->shallow_roots); i++) { + for (i = 0; i < wants->shallow_roots_len; i++) { char oid[GIT_OID_MAX_HEXSIZE + 1]; git_str shallow_buf = GIT_STR_INIT; - git_oid_tostr(oid, GIT_OID_MAX_HEXSIZE + 1, - git_shallowarray_get(wants->shallow_roots, i)); + git_oid_tostr(oid, GIT_OID_MAX_HEXSIZE + 1, &wants->shallow_roots[i]); git_str_puts(&shallow_buf, "shallow "); git_str_puts(&shallow_buf, oid); git_str_putc(&shallow_buf, '\n'); @@ -835,7 +834,7 @@ int git_pkt_buffer_wants( git_str_printf(buf,"%04x%s", (unsigned int)git_str_len(&deepen_buf) + 4, git_str_cstr(&deepen_buf)); git_str_dispose(&deepen_buf); - + if (git_str_oom(buf)) return -1; } diff --git a/src/libgit2/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c index 6167a8074..488ef07c0 100644 --- a/src/libgit2/transports/smart_protocol.c +++ b/src/libgit2/transports/smart_protocol.c @@ -364,7 +364,9 @@ static int cap_not_sup_err(const char *cap_name) } /* Disables server capabilities we're not interested in */ -static int setup_caps(transport_smart_caps *caps, const git_fetch_negotiation *wants) +static int setup_caps( + transport_smart_caps *caps, + const git_fetch_negotiation *wants) { if (wants->depth > 0) { if (!caps->shallow) @@ -376,7 +378,27 @@ static int setup_caps(transport_smart_caps *caps, const git_fetch_negotiation *w return 0; } -int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, const git_fetch_negotiation *wants) +static int setup_shallow_roots( + git_array_oid_t *out, + const git_fetch_negotiation *wants) +{ + git_array_clear(*out); + + if (wants->shallow_roots_len > 0) { + git_array_init_to_size(*out, wants->shallow_roots_len); + GIT_ERROR_CHECK_ALLOC(out->ptr); + + memcpy(out->ptr, wants->shallow_roots, + sizeof(git_oid) * wants->shallow_roots_len); + } + + return 0; +} + +int git_smart__negotiate_fetch( + git_transport *transport, + git_repository *repo, + const git_fetch_negotiation *wants) { transport_smart *t = (transport_smart *)transport; git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; @@ -388,7 +410,8 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c unsigned int i; git_oid oid; - if ((error = setup_caps(&t->caps, wants)) < 0) + if ((error = setup_caps(&t->caps, wants)) < 0 || + (error = setup_shallow_roots(&t->shallow_roots, wants)) < 0) return error; if ((error = git_pkt_buffer_wants(wants, &t->caps, &data)) < 0) @@ -411,9 +434,9 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c bool complete = false; if (pkt->type == GIT_PKT_SHALLOW) { - git_shallowarray_add(wants->shallow_roots, &pkt->oid); + error = git_oidarray__add(&t->shallow_roots, &pkt->oid); } else if (pkt->type == GIT_PKT_UNSHALLOW) { - git_shallowarray_remove(wants->shallow_roots, &pkt->oid); + git_oidarray__remove(&t->shallow_roots, &pkt->oid); } else if (pkt->type == GIT_PKT_FLUSH) { /* Server is done, stop processing shallow oids */ complete = true; @@ -431,6 +454,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c if (error < 0) goto on_error; } + /* * Our support for ACK extensions is simply to parse them. On * the first ACK we will accept that as enough common @@ -531,10 +555,11 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c goto on_error; if (t->cancelled.val) { - git_error_set(GIT_ERROR_NET, "The fetch was cancelled by the user"); + git_error_set(GIT_ERROR_NET, "the fetch was cancelled"); error = GIT_EUSER; goto on_error; } + if ((error = git_smart__negotiation_step(&t->parent, data.ptr, data.size)) < 0) goto on_error; @@ -562,6 +587,25 @@ on_error: return error; } +int git_smart__shallow_roots(git_oidarray *out, git_transport *transport) +{ + transport_smart *t = (transport_smart *)transport; + size_t len; + + GIT_ERROR_CHECK_ALLOC_MULTIPLY(&len, t->shallow_roots.size, sizeof(git_oid)); + + out->count = t->shallow_roots.size; + + if (len) { + out->ids = git__malloc(len); + memcpy(out->ids, t->shallow_roots.ptr, len); + } else { + out->ids = NULL; + } + + return 0; +} + static int no_sideband(transport_smart *t, struct git_odb_writepack *writepack, gitno_buffer *buf, git_indexer_progress *stats) { int recvd; -- cgit v1.2.1 From 437c5f5a0b6ae6068168081ac6422dba44cff31d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 8 May 2023 10:17:11 +0100 Subject: fetch: remove `unshallow` option The `depth` field is suitable to specify unshallowing; provide an enum to aide in specifying the `unshallow` value. --- src/libgit2/fetch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/libgit2') diff --git a/src/libgit2/fetch.c b/src/libgit2/fetch.c index b43425215..5bbef87f4 100644 --- a/src/libgit2/fetch.c +++ b/src/libgit2/fetch.c @@ -174,10 +174,8 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) remote->need_pack = 0; if (opts) { - GIT_ASSERT_ARG(opts->unshallow == 0 || opts->depth == 0); GIT_ASSERT_ARG(opts->depth >= 0); - - remote->nego.depth = opts->unshallow ? INT_MAX : opts->depth; + remote->nego.depth = opts->depth; } if (filter_wants(remote, opts) < 0) -- cgit v1.2.1